forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
LinkTable.cpp
1 
9 #include "LinkTable.h"
10 
11 namespace forest {
12 
14 LinkTable::LinkTable(int maxLnk1) : maxLnk(maxLnk1) {
15  map = new HashMap<uint64_t,Entry,Hash::u64>(maxLnk,false);
16  padrMap = new HashSet<fAdr_t,Hash::s32>(maxLnk,false);
17 };
18 
21  delete map; delete padrMap;
22 }
23 
37 int LinkTable::addEntry(int lnk, ipa_t peerIp, ipp_t peerPort, uint64_t nonce) {
38  Entry e;
39  e.iface= 0; e.isConnected = false; e.nonce = nonce;
40  e.peerIp = peerIp; e.peerPort = peerPort;
41  e.peerAdr = 0; e.peerType = Forest::UNDEF_NODE;
46 
47  if (lnk == 0) lnk = map->put(nonce,e);
48  else lnk = map->put(nonce,e,lnk);
49  return lnk;
50 }
51 
59 bool LinkTable::connect(int lnk, ipa_t peerIp, ipp_t peerPort) {
60  if (!valid(lnk)) return false;
61  Entry& e = getEntry(lnk);
62  if (e.isConnected == true) return false; // already connected
63  if (map->find(e.nonce) != lnk) return false;
64  if (!map->rekey(lnk, hashkey(peerIp,peerPort))) return false;
65  e.peerIp = peerIp; e.peerPort = peerPort; e.isConnected = true;
66  return true;
67 }
68 
73 bool LinkTable::removeEntry(int lnk) {
74  if (!valid(lnk)) return false;
75  Entry& e = getEntry(lnk);
76  if (e.isConnected == true)
77  map->remove(hashkey(e.peerIp,e.peerPort));
78  else
79  map->remove(e.nonce);
80  return true;
81 }
82 
87 void LinkTable::setPeerAdr(int lnk, fAdr_t adr) {
88  if (!valid(lnk)) return;
89  Entry& e = getEntry(lnk);
90 
91  if (e.peerAdr != 0) padrMap->remove(e.peerAdr);
92  if (adr != 0) padrMap->insert(adr,lnk);
93  e.peerAdr = adr;
94 }
95 
100 bool LinkTable::checkEntry(int lnk) {
101  if (!valid(lnk)) return false;
102  Entry& e = getEntry(lnk);
103  // the forest address of every peer must be a valid unicast address
104  if (!Forest::validUcastAdr(e.peerAdr)) return false;
105 
106  // only a router may use the forest port number
108  return false;
109  return true;
110 }
111 
129 int LinkTable::readEntry(istream& in) {
130  int lnk, iface; RateSpec rs;
131  ipa_t peerIp; int peerPort;
132  Forest::ntyp_t peerType; int peerAdr;
133  string typStr;
134 
135  Util::skipBlank(in);
136  if ( !Util::readInt(in,lnk) ||
137  !Util::readInt(in,iface) ||
138  !Np4d::readIpAdr(in,peerIp) || !Util::verify(in,':') ||
139  !Util::readInt(in,peerPort) ||
140  !Util::readWord(in,typStr) ||
141  !Forest::readForestAdr(in,peerAdr) ||
142  !rs.read(in)) {
143  return 0;
144  }
145  Util::nextLine(in);
146 
147  peerType = Forest::getNodeType(typStr);
148  if (peerType == Forest::UNDEF_NODE) return 0;
149 
150  if (!addEntry(lnk,peerIp,peerPort,0)) return 0;
151  Entry& e = getEntry(lnk);
152  e.iface = iface;
153  e.peerType = (Forest::ntyp_t) peerType;
154  e.peerAdr = peerAdr;
155  e.rates = rs; e.availRates = rs;
156 
157  if (!checkEntry(lnk)) { removeEntry(lnk); return 0; }
158 
159  return lnk;
160 }
161 
172 bool LinkTable::read(istream& in) {
173  int num;
174  Util::skipBlank(in);
175  if (!Util::readInt(in,num)) return false;
176  Util::nextLine(in);
177  for (int i = 1; i <= num; i++) {
178  if (readEntry(in) == 0) {
179  cerr << "LinkTable::read: could not read "
180  << i << "-th table entry" << endl;
181  return false;
182  }
183  }
184  return true;
185 }
186 
192 string LinkTable::link2string(int lnk) const {
193  if (!valid(lnk)) { return ""; }
194  stringstream ss;
195  ss << setw(5) << right << lnk;
196  ss << getEntry(lnk);
197  return ss.str();
198 }
199 
204 string LinkTable::toString() const {
205  stringstream ss;
206  ss << map->size() << endl;
207  ss << "# link iface peerIp:port peerType peerAdr ";
208  ss << " rates avail rates comtree count\n";
209  for (int i = firstLink(); i != 0; i = nextLink(i))
210  ss << link2string(i) << endl;
211  return ss.str();
212 }
213 
214 /*
215 #define pack8(x) (*buf = *((char*) x), buf += 1)
216 #define pack16(x) (*buf = *((char*) htons(x)), buf += sizeof(uint16_t))
217 #define pack32(x) (*buf = *((char*) htonl(x)), buf += sizeof(uint32_t))
218 #define pack64(x) ( pack32(((x)>>32)&0xffffffff), pack32((x)&0xffffffff))
219 #define packRspec(x) ( pack32(x.bitRateUp), pack32(x.bitRateDown), \
220  pack32(x.pktRateUp), pack32(x.pktRateDown) )
221 */
222 
247 /*
248 #define unpack8(x) (x = *buf, buf += 1)
249 #define unpack16(x) (x = ntohs(*((uint16_t*) buf)), buf += sizeof(uint16_t))
250 #define unpack32(x) (x = ntohl(*((uint32_t*) buf)), buf += sizeof(uint32_t))
251 #define unpack64(x) (x = ntohl(*((uint32_t*) buf)), buf += sizeof(uint32_t), \
252  x |= ntohl(*((uint32_t*) buf)), buf += sizeof(uint32_t))
253 #define unpackRspec(x) (pack32(x.bitRateUp), pack32(x.bitRateDown), \
254  pack32(x.pktRateUp), pack32(x.pktRateDown) )
255  */
256 
283 } // ends namespace
284