forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
Np4d.cpp
Go to the documentation of this file.
1 
9 #include "Np4d.h"
10 
11 namespace forest {
12 
13 
17 ipa_t Np4d::ipAddress(const char *ips) {
18  ipa_t ipa = inet_addr(ips);
19  if (ipa == INADDR_NONE) return 0;
20  return ntohl(ipa);
21 }
22 
27 string Np4d::ip2string(ipa_t ipa) {
28  // ugly code thanks to inet_ntoa's dreadful interface
29  struct in_addr ipa_struct;
30  ipa_struct.s_addr = htonl(ipa);
31  string s = inet_ntoa(ipa_struct);
32  return s;
33 }
34 
40 bool Np4d::readIpAdr(istream& in, ipa_t& ipa) {
41  int adr[4];
42 
43  if (!Util::readInt(in,adr[0]) || !Util::verify(in,'.') ||
44  !Util::readInt(in,adr[1]) || !Util::verify(in,'.') ||
45  !Util::readInt(in,adr[2]) || !Util::verify(in,'.') ||
46  !Util::readInt(in,adr[3]))
47  return false;
48  ipa = ((adr[0] & 0xff) << 24) | ((adr[1] & 0xff) << 16) |
49  ((adr[2] & 0xff) << 8) | (adr[3] & 0xff);
50  return true;
51 }
52 
57 ipa_t Np4d::getIpAdr(const char* hostName) {
58  hostent* host = gethostbyname(hostName);
59  if (host == NULL) return 0;
60  return ntohl(*((ipa_t*) &host->h_addr_list[0][0]));
61 }
62 
67  char myName[1001];
68  if (gethostname(myName, 1000) != 0) return 0;
69  return getIpAdr(myName);
70 }
71 
78 void Np4d::initSockAdr(ipa_t ipa, ipp_t port, sockaddr_in *sap) {
79  bzero(sap, sizeof(sockaddr_in));
80  sap->sin_family = AF_INET;
81  sap->sin_addr.s_addr = (ipa == 0 ? INADDR_ANY : htonl(ipa));
82  sap->sin_port = htons(port);
83 }
84 
90 void Np4d::extractSockAdr(sockaddr_in *sap, ipa_t& ipa, ipp_t& ipp) {
91  ipa = ntohl(sap->sin_addr.s_addr);
92  ipp = ntohs(sap->sin_port);
93 }
94 
99 ipp_t Np4d::getSockPort(int sock) {
100  sockaddr_in sa; socklen_t len = sizeof(sa);
101  if (getsockname(sock, (struct sockaddr *) &sa, &len) < 0)
102  return 0;
103  return ntohs(sa.sin_port);
104 }
105 
110 ipa_t Np4d::getSockIp(int sock) {
111  sockaddr_in sa; socklen_t len = sizeof(sa);
112  if (getsockname(sock, (struct sockaddr *) &sa, &len) < 0)
113  return 0;
114  return ntohl(sa.sin_addr.s_addr);
115 }
116 
121 ipa_t Np4d::getPeerIp(int sock) {
122  sockaddr_in sa; socklen_t len = sizeof(sa);
123  if (getpeername(sock, (struct sockaddr *) &sa, &len) < 0)
124  return 0;
125  return ntohl(sa.sin_addr.s_addr);
126 }
127 
132 bool Np4d::nonblock(int sock) {
133  int flags;
134  if ((flags = fcntl(sock, F_GETFL, 0)) < 0) return false;
135  flags |= O_NONBLOCK;
136  if ((flags = fcntl(sock, F_SETFL, flags)) < 0) return false;
137  return true;
138 }
139 
144  return socket(AF_INET,SOCK_DGRAM,0);
145 }
146 
151  return socket(AF_INET,SOCK_STREAM,0);
152 }
153 
161 bool Np4d::bind4d(int sock, ipa_t ipa, ipp_t ipp) {
162  sockaddr_in sa;
163  initSockAdr(ipa,ipp,&sa);
164 
165  int x = bind(sock,(struct sockaddr *) &sa, sizeof(sa));
166 
167  return (x == 0);
168 }
169 
175 bool Np4d::listen4d(int sock) { return (listen(sock, 200) == 0); }
176 
182 int Np4d::accept4d(int sock) { return accept(sock,NULL,NULL); }
183 
193 int Np4d::accept4d(int sock, ipa_t& ipa, ipp_t& ipp) {
194  sockaddr_in sa; socklen_t len = sizeof(sa);
195  sock = accept(sock,(struct sockaddr *) &sa, &len);
196  if (sock < 0) return -1;
197  extractSockAdr(&sa,ipa,ipp);
198  return sock;
199 }
200 
208 bool Np4d::connect4d(int sock, ipa_t ipa, ipp_t ipp) {
209  sockaddr_in sa; initSockAdr(ipa,ipp,&sa);
210  return (connect(sock,(struct sockaddr *) &sa,sizeof(sa)) == 0);
211 }
212 
222 int Np4d::sendto4d(int sock, void* buf, int leng, ipa_t ipa, ipp_t ipp) {
223  sockaddr_in sa; initSockAdr(ipa,ipp,&sa);
224  return sendto(sock,buf,leng,0,(struct sockaddr *) &sa, sizeof(sa));
225 }
226 
234 int Np4d::recv4d(int sock, void* buf, int leng) {
235  return recv(sock,buf,leng,0);
236 }
237 
249 int Np4d::recvfrom4d(int sock, void* buf, int leng, ipa_t& ipa, ipp_t& ipp) {
250  sockaddr_in sa; initSockAdr(ipa,ipp,&sa);
251  socklen_t socklen = sizeof(sa);
252  int nbytes = recvfrom(sock,buf,leng,0,(struct sockaddr *) &sa,&socklen);
253  extractSockAdr(&sa,ipa,ipp);
254  return nbytes;
255 }
256 
262 bool Np4d::hasData(int sock) {
263  struct pollfd ps;
264  ps.fd = sock; ps.events = POLLIN;
265  return poll(&ps, 1, 0) == 1;
266 }
267 
272 int Np4d::dataAvail(int sock) {
273  int dAvail; socklen_t daSize = sizeof(dAvail);
274 #ifdef SO_NREAD
275  if (getsockopt(sock, SOL_SOCKET, SO_NREAD, &dAvail, &daSize) == -1)
276 #else
277  if (ioctl(sock, SIOCINQ, &dAvail ) == -1)
278 #endif
279  return -1;
280  return dAvail;
281 }
282 
288 int Np4d::spaceAvail(int sock) {
289  int sbSize; socklen_t sbSizeSize = sizeof(sbSize);
290  if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sbSize, &sbSizeSize) != 0)
291  return -1;
292  int dQueued; socklen_t dqSize = sizeof(dQueued);
293 #ifdef SO_NWRITE
294  if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &dQueued, &dqSize) != 0)
295 #else
296  if (ioctl(sock, SIOCOUTQ, &dQueued ) == -1)
297 #endif
298  return -1;
299  return sbSize - dQueued;
300 }
301 
310 bool Np4d::recvInt(int sock, uint32_t& val) {
311  if (dataAvail(sock) < (int) sizeof(uint32_t)) return false;
312  uint32_t temp;
313  int nbytes = recv(sock, (void *) &temp, sizeof(uint32_t), 0);
314  if (nbytes != sizeof(uint32_t))
315  Util::fatal("Np4d::recvInt: can't receive integer");
316  val = ntohl(temp);
317  return true;
318 }
319 
320 bool Np4d::recvIntBlock(int sock, uint32_t& val) {
321  char temp[sizeof(uint32_t)];
322  int nbytes; int rem = sizeof(uint32_t);
323  while(true) {
324  nbytes = recv(sock, (void *) &temp[sizeof(uint32_t)-rem], sizeof(uint32_t), 0);
325  if(nbytes < 0) return nbytes;
326  rem -= nbytes;
327  if(rem == 0) break;
328  }
329  if (nbytes != sizeof(uint32_t))
330  Util::fatal("Np4d::recvInt: can't receive integer");
331  val = *((uint32_t*) temp);
332  val = ntohl(val);
333  return true;
334 }
335 
342 bool Np4d::sendInt(int sock, uint32_t val) {
343  if (spaceAvail(sock) < (int) sizeof(uint32_t)) return false;
344  val = htonl(val);
345  int nbytes = send(sock, (void *) &val, sizeof(uint32_t), 0);
346  if (nbytes != sizeof(uint32_t))
347  Util::fatal("Np4d::sendInt: can't send integer");
348  return true;
349 }
350 
351 bool Np4d::sendIntBlock(int sock, uint32_t val) {
352  val = htonl(val);
353  int nbytes = send(sock, (void *) &val, sizeof(uint32_t), 0);
354  if (nbytes != sizeof(uint32_t))
355  Util::fatal("Np4d::sendInt: can't send integer");
356  return true;
357 }
368 bool Np4d::recvIntVec(int sock, uint32_t vec[], int length) {
369  int vecSiz = length * sizeof(uint32_t);
370  if (dataAvail(sock) < vecSiz) return false;
371  uint32_t buf[length];
372  int nbytes = recv(sock,(void *) buf, vecSiz, 0);
373  if (nbytes != vecSiz)
374  Util::fatal("Np4d::recvIntVec: can't receive vector");
375  for (int i = 0; i < length; i++) vec[i] = ntohl(buf[i]);
376  return true;
377 }
378 
386 bool Np4d::sendIntVec(int sock, uint32_t vec[], int length) {
387  socklen_t vecSiz = length * sizeof(uint32_t);
388  if (spaceAvail(sock) < (int) vecSiz) return false;
389  uint32_t buf[length];
390  for (int i = 0; i < length; i++) buf[i] = htonl(vec[i]);
391  int nbytes = send(sock, (void *) buf, vecSiz, 0);
392  if (nbytes != (int) vecSiz)
393  Util::fatal("Np4d::sendIntVec: can't send vector");
394  return true;
395 }
396 
416 int Np4d::recvBuf(int sock, char* buf, int buflen) {
417  uint32_t length;
418  int nbytes = recv(sock,(void *) &length, sizeof(uint32_t), MSG_PEEK);
419  if (nbytes <= 0) return nbytes;
420  if (nbytes != sizeof(uint32_t)) return -1;
421  length = ntohl(length);
422  if (dataAvail(sock) < ((int) (length + sizeof(uint32_t)))) return -1;
423  nbytes = recv(sock,(void *) &length, sizeof(uint32_t), 0);
424  length = min<int>(ntohl(length), buflen);
425  nbytes = recv(sock,(void *) buf, length, 0);
426  return nbytes;
427 }
428 
429 int Np4d::recvBufBlock(int sock, char* buf, int buflen) {
430  int rem = sizeof(uint32_t); char lenBuf[sizeof(uint32_t)]; int nbytes;
431  while(true) {
432  nbytes = recv(sock,&lenBuf[sizeof(uint32_t)-rem],
433  sizeof(uint32_t),0);
434  if(nbytes < 0) return nbytes;
435  rem -= nbytes;
436  if (rem == 0) break;
437  }
438  uint32_t length = *((uint32_t *) lenBuf);
439  length = ntohl(length);
440  length = min<int>(length, buflen);
441  rem = length;
442  while(true) {
443  nbytes = recv(sock,(void *) &buf[length-rem], length, 0);
444  if(nbytes < 0) return nbytes;
445  rem -= nbytes;
446  if( rem == 0) break;
447  }
448  return nbytes;
449 }
450 
451 int Np4d::sendBuf(int sock, char* buf, int buflen) {
452  if (spaceAvail(sock) < buflen + (int) sizeof(uint32_t))
453  return -1;
454  buflen = htonl(buflen);
455  int nbytes = send(sock, (void *) &buflen, sizeof(uint32_t), 0);
456  if (nbytes != sizeof(uint32_t))
457  Util::fatal("Np4d::sendBuf: can't send buffer");
458  buflen = ntohl(buflen);
459  nbytes = send(sock, (void *) buf, buflen, 0);
460  if (nbytes != buflen)
461  Util::fatal("Np4d::sendBuf: can't send buffer");
462  return buflen;
463 }
464 
465 int Np4d::sendBufBlock(int sock, char* buf, int buflen) {
466  int length = htonl(buflen);
467  int nbytes = send(sock, (void *) &length, sizeof(uint32_t), 0);
468  if (nbytes != sizeof(uint32_t))
469  Util::fatal("Np4d::sendBuf: can't send buffer");
470  nbytes = send(sock, (void *) buf, buflen, 0);
471  if (nbytes != buflen)
472  Util::fatal("Np4d::sendBuf: can't send buffer");
473  return buflen;
474 }
475 
482 int Np4d::sendString(int sock, const string& s) {
483  const char *p; p = s.c_str();
484  int numLeft = s.size(); // do not include EOS
485  while (numLeft > 0) {
486  int nbytes = write(sock,(void *) p,numLeft);
487  if (nbytes <= 0) {
488  if (nbytes < 0 && errno == EINTR)
489  nbytes = 0;
490  else return -1;
491  }
492  numLeft -= nbytes; p += nbytes;
493  }
494  return s.size();
495 }
496 
497 } // ends namespace
498