11 using namespace forest;
33 for (
int i = 1; i < argc; i++) {
35 if (s.compare(0,10,
"mode=local") == 0) {
37 }
else if (s.compare(0,11,
"mode=remote") == 0) {
39 }
else if (s.compare(0,6,
"myAdr=") == 0) {
41 }
else if (s.compare(0,7,
"bootIp=") == 0) {
43 }
else if (s.compare(0,6,
"nmAdr=") == 0) {
45 }
else if (s.compare(0,5,
"nmIp=") == 0) {
47 }
else if (s.compare(0,6,
"ccAdr=") == 0) {
49 }
else if (s.compare(0,13,
"firstLeafAdr=") == 0) {
51 }
else if (s.compare(0,12,
"lastLeafAdr=") == 0) {
53 }
else if (s.compare(0,6,
"ifTbl=") == 0) {
54 args.
ifTbl = &argv[i][6];
55 }
else if (s.compare(0,7,
"lnkTbl=") == 0) {
57 }
else if (s.compare(0,8,
"comtTbl=") == 0) {
59 }
else if (s.compare(0,7,
"rteTbl=") == 0) {
61 }
else if (s.compare(0,9,
"statSpec=") == 0) {
63 }
else if (s.compare(0,8,
"finTime=") == 0) {
64 sscanf(&argv[i][8],
"%d",&args.
finTime);
66 cerr <<
"unrecognized argument: " << argv[i] << endl;
70 if (args.
mode.compare(
"local") == 0 &&
73 cerr <<
"processArgs: local configuration requires myAdr, "
74 "firstLeafAdr, lastLeafAdr and that firstLeafAdr "
75 "be no larger than lastLeafAdr\n";
77 }
else if (args.
mode.compare(
"remote") == 0 &&
80 cerr <<
"processArgs: remote configuration requires bootIp, "
81 "myAdr, netMgrIp and netMgrAdr\n";
89 int main(
int argc,
char *argv[]) {
92 fatal(
"fRouter: error processing command line arguments");
93 bool booting = args.
mode.compare(
"remote") == 0;
96 if (!router.readTables(args))
97 fatal(
"router: could not read specified config files");
100 fatal(
"router: inconsistency in config files");
116 : booting(booting1) {
142 pending =
new map<uint64_t,CpInfo>;
145 RouterCore::~RouterCore() {
147 delete rt;
delete ctt;
delete lt;
delete ift;
delete ps;
158 if (config.
ifTbl.compare(
"") != 0) {
159 ifstream fs; fs.open(config.
ifTbl.c_str());
160 if (fs.fail() || !
ift->
read(fs)) {
161 cerr <<
"RouterCore::init: can't read "
162 <<
"interface table\n";
167 if (config.
lnkTbl.compare(
"") != 0) {
168 ifstream fs; fs.open(config.
lnkTbl.c_str());
169 if (fs.fail() || !
lt->
read(fs)) {
170 cerr <<
"RouterCore::init: can't read "
176 if (config.
comtTbl.compare(
"") != 0) {
177 ifstream fs; fs.open(config.
comtTbl.c_str());
178 if (fs.fail() || !
ctt->
read(fs)) {
179 cerr <<
"RouterCore::init: can't read "
180 <<
"comtree table\n";
185 if (config.
rteTbl.compare(
"") != 0) {
186 ifstream fs; fs.open(config.
rteTbl.c_str());
187 if (fs.fail() || !
rt->
read(fs)) {
188 cerr <<
"RouterCore::init: can't read "
189 <<
"routing table\n";
194 if (config.
statSpec.compare(
"") != 0) {
195 ifstream fs; fs.open(config.
statSpec.c_str());
196 if (fs.fail() || !
sm->read(fs)) {
197 cerr <<
"RouterCore::init: can't read "
198 <<
"statistics spec\n";
229 if (
iop->ready(iface))
continue;
231 cerr <<
"RouterCore::setupIfaces: could not "
232 "setup interface " << iface << endl;
263 qm->setLinkRates(lnk,
lt->getRates(lnk));
271 set<int>::iterator p;
272 for (p = links.begin(); p != links.end(); p++) {
275 if (qid == 0)
return false;
277 qm->setQRates(qid,rs);
279 qm->setQLimits(qid,100,200000);
281 qm->setQLimits(qid,50,100000);
282 sm->clearQuStats(qid);
300 cerr <<
"RouterCore::checkTables: specified default iface "
307 if (
ift->getIpAdr(iface) == 0) {
308 cerr <<
"RouterCore::checkTables: interface "
309 << iface <<
" has zero for IP address\n";
320 iface =
lt->getIface(lnk);
322 cerr <<
"RouterCore::checkTables: interface " << iface
323 <<
" for link " << lnk <<
" is not valid\n";
326 if (
lt->getPeerIpAdr(lnk) == 0 &&
328 cerr <<
"RouterCore::checkTables: invalid peer IP "
329 <<
"for link " << lnk << endl;
333 cerr <<
"RouterCore::checkTables: invalid peer address "
334 <<
"for link " << lnk << endl;
349 cerr <<
"RouterCore::checkTables: parent link "
350 << plnk <<
" not consistent with pcLnk\n";
354 cerr <<
"RouterCore::checkTables: parent link "
355 << plnk <<
" of core node does not lead to "
356 <<
"another core node\n";
360 set<int>::iterator p;
361 for (p = links.begin(); p != links.end(); p++) {
364 cerr <<
"RouterCore::checkTables: link "
365 << lnk <<
" in comtree " << comt
366 <<
" not in link table" << endl;
372 cerr <<
"RouterCore::checkTables: dest addr "
373 <<
"for " << lnk <<
" in comtree " << comt
374 <<
" is not valid" << endl;
379 cerr <<
"RouterCore::checkTables: queue id "
380 <<
"for " << lnk <<
" in comtree " << comt
381 <<
" is zero" << endl;
387 for (p = rtrLinks.begin(); p != rtrLinks.end(); p++) {
390 cerr <<
"RouterCore::checkTables: router link "
391 << lnk <<
" is not valid in comtree "
396 cerr <<
"RouterCore::checkTables: router link "
397 << lnk <<
" in comtree " << comt
398 <<
" connects to non-router peer\n";
403 for (p = coreLinks.begin(); p != coreLinks.end(); p++) {
406 cerr <<
"RouterCore::checkTables: core link "
407 << lnk <<
" is not a router link "
432 if (!minRates.leq(ifRates) || !ifRates.
leq(maxRates)) {
433 cerr <<
"RouterCore::setAvailRates: interface rates "
434 "outside allowed range\n";
437 ift->getAvailRates(iface) = ifRates;
439 if (!success)
return false;
443 if (!minRates.leq(lnkRates) || !lnkRates.
leq(maxRates)) {
444 cerr <<
"RouterCore::setAvailRates: link rates "
445 "outside allowed range\n";
448 iface =
lt->getIface(lnk);
450 if (!lnkRates.
leq(ifAvail)) {
451 cerr <<
"RouterCore::setAvailRates: oversubscribing "
452 "interface " << iface << endl;
455 ift->getAvailRates(iface).subtract(lnkRates);
457 lt->getAvailRates(lnk) = lnkRates;
458 sm->clearLnkStats(lnk);
460 if (!success)
return false;
465 set<int>::iterator p;
466 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
469 if (!comtRates.
leq(
lt->getAvailRates(lnk))) {
470 cerr <<
"RouterCore::setAvailRates: "
471 "oversubscribing link "
475 lt->getAvailRates(lnk).subtract(comtRates);
489 set<int>::iterator p;
490 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
492 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
497 if (
rt->getRteIndex(comt,peerAdr) != 0)
499 rt->addEntry(comt,peerAdr,cLnk);
509 out <<
"Interface Table\n\n" <<
ift->
toString(s) << endl;
510 out <<
"Link Table\n\n" <<
lt->
toString(s) << endl;
511 out <<
"Comtree Table\n\n" <<
ctt->
toString(s) << endl;
512 out <<
"Routing Table\n\n" <<
rt->
toString(s) << endl;
513 out <<
"Statistics\n\n" <<
sm->
toString(s) << endl;
548 fatal(
"RouterCore:run: could not setup boot socket\n");
552 CtlPkt cp(CtlPkt::BOOT_ROUTER,CtlPkt::REQUEST,0);
554 fatal(
"RouterCore::run: could not send boot request\n");
558 uint64_t statsTime = 0;
560 int controlCount = 20;
565 finishTime *= 1000000000;
566 while (finishTime == 0 ||
now < finishTime) {
570 pktx px =
iop->receive();
579 }
else if (booting) {
599 while ((px =
qm->
deq(lnk,
now)) != 0) {
606 if (!ctlQ.empty() && (didNothing || --controlCount <= 0)) {
615 if (
now - statsTime > 300000000) {
623 if (didNothing) { usleep(1000); }
632 cout <<
sm->iPktCnt(0) <<
" packets received, "
633 <<
sm->oPktCnt(0) <<
" packets sent\n";
634 cout <<
sm->iPktCnt(-1) <<
" from routers, "
635 <<
sm->oPktCnt(-1) <<
" to routers\n";
636 cout <<
sm->iPktCnt(-2) <<
" from clients, "
637 <<
sm->oPktCnt(-2) <<
" to clients\n";
670 if (inLink == 0)
return false;
679 if (
lt->getPeerAdr(inLink) != p.
srcAdr)
return false;
692 comt != (
int) Forest::CONNECT_COMT)
722 int rcLnk =
rt->getLink(rtx);
755 int qvec[
nLnks];
int n = 0;
764 set<int>::iterator lp;
765 for (lp = rtrLinks.begin(); lp != rtrLinks.end(); lp++) {
766 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
768 if (pZip == myZip && peerZip != myZip)
continue;
769 if (lnk == inLink)
continue;
777 set<int>::iterator lp;
778 for (lp = coreLinks.begin(); lp != coreLinks.end(); lp++) {
779 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
780 if (lnk == inLink || lnk == pLink)
continue;
784 if (pLink != 0 && pLink != inLink) {
789 set<int>& subLinks =
rt->getSubLinks(rtx);
790 for (lp = subLinks.begin(); lp !=subLinks.end(); lp++) {
791 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
792 if (lnk == inLink)
continue;
798 if (n == 0) {
ps->
free(px);
return; }
802 for (
int i = 0; i < n-1; i++) {
832 (p1.payload())[0] = htonl(p.
dstAdr);
853 int adr = ntohl((p.payload())[0]);
865 int dcLnk =
rt->getLink(rtx);
int dLnk =
ctt->
getLink(dcLnk);
880 uint32_t *pp = p.payload();
887 uint64_t seq = ntohl(pp[0]);
892 map<uint64_t,CpInfo>::iterator it =
pending->find(seq);
905 bool propagate =
false;
909 int addcnt = ntohl(pp[2]);
910 if (addcnt < 0 || addcnt > 350 ||
914 for (
int i = 3; i <= addcnt + 2; i++) {
917 rtx =
rt->getRteIndex(comt,addr);
919 rtx =
rt->addEntry(comt,addr,cLnk);
927 int dropcnt = ntohl(pp[addcnt+3]);
928 if (dropcnt < 0 || addcnt + dropcnt > 350 ||
932 for (
int i = addcnt + 4; i <= addcnt + dropcnt + 3; i++) {
935 rtx =
rt->getRteIndex(comt,addr);
936 if (rtx == 0)
continue;
939 rt->removeEntry(rtx);
949 pair<uint64_t,CpInfo> cpp;
951 pp[0] = htonl((uint32_t) (
seqNum >> 32));
952 pp[1] = htonl((uint32_t) (
seqNum & 0xffffffff));
958 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
979 if (p.
srcAdr !=
lt->getPeerAdr(inLnk) ||
983 uint64_t nonce = ntohl(p.payload()[0]);
985 nonce |= ntohl(p.payload()[1]);
986 if (nonce !=
lt->getNonce(inLnk)) {
ps->
free(px);
return; }
988 uint64_t x = 1; x <<= 63; x |= nonce;
998 lt->setConnectStatus(inLnk,
true);
1000 CtlPkt cp(CtlPkt::CLIENT_CONNECT,CtlPkt::REQUEST,0);
1005 lt->setConnectStatus(inLnk,
false);
1009 CtlPkt cp(CtlPkt::CLIENT_DISCONNECT,CtlPkt::REQUEST,0);
1017 iop->send(px,inLnk);
1034 cerr <<
"RouterCore::handleCtlPkt: misformatted control "
1036 cp.reset(cp.type,CtlPkt::NEG_REPLY,cp.seqNum);
1037 cp.mode = CtlPkt::NEG_REPLY;
1038 cp.errMsg =
"misformatted control packet";
1042 if (cp.mode != CtlPkt::REQUEST) {
1047 CtlPkt reply(cp.type,CtlPkt::POS_REPLY,cp.seqNum);
1052 case CtlPkt::ADD_IFACE:
addIface(cp,reply);
break;
1053 case CtlPkt::DROP_IFACE: dropIface(cp,reply);
break;
1054 case CtlPkt::GET_IFACE: getIface(cp,reply);
break;
1055 case CtlPkt::MOD_IFACE: modIface(cp,reply);
break;
1058 case CtlPkt::ADD_LINK: addLink(cp,reply);
break;
1059 case CtlPkt::DROP_LINK: dropLink(cp,reply);
break;
1060 case CtlPkt::GET_LINK: getLink(cp,reply);
break;
1061 case CtlPkt::MOD_LINK: modLink(cp,reply);
break;
1064 case CtlPkt::ADD_COMTREE: addComtree(cp,reply);
break;
1065 case CtlPkt::DROP_COMTREE: dropComtree(cp,reply);
break;
1066 case CtlPkt::GET_COMTREE: getComtree(cp,reply);
break;
1067 case CtlPkt::MOD_COMTREE: modComtree(cp,reply);
break;
1068 case CtlPkt::ADD_COMTREE_LINK: addComtreeLink(cp,reply);
break;
1069 case CtlPkt::DROP_COMTREE_LINK: dropComtreeLink(cp,reply);
break;
1070 case CtlPkt::GET_COMTREE_LINK: getComtreeLink(cp,reply);
break;
1071 case CtlPkt::MOD_COMTREE_LINK: modComtreeLink(cp,reply);
break;
1074 case CtlPkt::ADD_ROUTE: addRoute(cp,reply);
break;
1075 case CtlPkt::DROP_ROUTE: dropRoute(cp,reply);
break;
1076 case CtlPkt::GET_ROUTE: getRoute(cp,reply);
break;
1077 case CtlPkt::MOD_ROUTE: modRoute(cp,reply);
break;
1080 case CtlPkt::SET_LEAF_RANGE:
setLeafRange(cp,reply);
break;
1082 case CtlPkt::GET_LINK_SET:
getLinkSet(px,reply);
break;
1084 cerr <<
"unrecognized control packet type " << cp.type
1086 reply.errMsg =
"invalid control packet for router";
1087 reply.mode = CtlPkt::NEG_REPLY;
1108 int iface = cp.
iface;
1118 if (cp.
iface !=
ift->getIpAdr(iface) ||
1119 !rs.equals(
ift->getRates(iface))) {
1120 reply.
errMsg =
"add iface: requested interface "
1121 "conflicts with existing interface";
1122 reply.
mode = CtlPkt::NEG_REPLY;
1126 reply.ip1 =
ift->getIpAdr(iface);
1127 reply.port1 =
ift->getPort(iface);
1129 }
else if (!
ift->
addEntry(iface, cp.ip1, 0, rs)) {
1130 reply.
errMsg =
"add iface: cannot add interface";
1131 reply.
mode = CtlPkt::NEG_REPLY;
1134 reply.
errMsg =
"add iface: could not setup interface";
1135 reply.
mode = CtlPkt::NEG_REPLY;
1138 reply.ip1 =
ift->getIpAdr(iface);
1139 reply.port1 =
ift->getPort(iface);
1143 bool RouterCore::dropIface(
CtlPkt& cp,
CtlPkt& reply) {
1149 int iface = cp.
iface;
1151 reply.
iface = iface;
1152 reply.ip1 =
ift->getIpAdr(iface);
1153 reply.port1 =
ift->getPort(iface);
1154 reply.rspec1 =
ift->getRates(iface);
1155 reply.
rspec2 =
ift->getAvailRates(iface);
1158 reply.
errMsg =
"get iface: invalid interface";
1159 reply.
mode = CtlPkt::NEG_REPLY;
1164 int iface = cp.
iface;
1166 ift->getRates(iface) = cp.rspec1;
1169 reply.
errMsg =
"mod iface: invalid interface";
1170 reply.
mode = CtlPkt::NEG_REPLY;
1177 reply.
errMsg =
"add link: adding link to router, but no peer "
1179 reply.
mode = CtlPkt::NEG_REPLY;
1182 int iface = cp.
iface;
1184 int xlnk =
lt->
lookup(cp.ip1,cp.port1);
1186 if (cp.
link != xlnk ||
1187 (peerType !=
lt->getPeerType(xlnk)) ||
1188 (cp.
iface !=
lt->getIface(xlnk)) ||
1189 (cp.adr1 != 0 && cp.adr1 !=
lt->getPeerAdr(xlnk)) ||
1190 (cp.ip1 != 0 && cp.ip1 !=
ift->getIpAdr(iface)) ||
1191 (cp.port1 != 0 && cp.port1 !=
ift->getPort(iface))) {
1192 reply.
errMsg =
"add link: new link conflicts "
1193 "with existing link";
1194 reply.
mode = CtlPkt::NEG_REPLY;
1199 reply.adr1 =
lt->getPeerAdr(xlnk);
1200 reply.ip1 =
lt->getPeerIpAdr(xlnk);
1209 if (!rs.leq(availRates)) {
1210 reply.
errMsg =
"add link: requested link "
1211 "exceeds interface capacity";
1212 reply.
mode = CtlPkt::NEG_REPLY;
1231 reply.
errMsg =
"add link: cannot add requested link";
1232 reply.
mode = CtlPkt::NEG_REPLY;
1244 reply.
errMsg =
"add link: cannot add link using "
1245 "specified address";
1246 reply.
mode = CtlPkt::NEG_REPLY;
1253 lt->setIface(lnk,iface);
1254 lt->setPeerType(lnk,peerType);
1255 lt->setConnectStatus(lnk,
false);
1256 sm->clearLnkStats(lnk);
1257 if (peerType ==
Forest::ROUTER && cp.ip1 != 0 && cp.port1 != 0) {
1263 reply.adr1 =
lt->getPeerAdr(lnk);
1272 void RouterCore::dropLink(
int lnk) {
1273 int *comtVec =
new int[
lt->getComtSet(lnk).size()];
1275 for (
int comt :
lt->getComtSet(lnk)) comtVec[i++] = comt;
1277 int ctx = comtVec[i];
1279 dropComtreeLink(ctx,lnk,cLnk);
1281 int iface =
lt->getIface(lnk);
1282 ift->getAvailRates(iface).add(
lt->getRates(lnk));
1291 reply.
iface =
lt->getIface(link);
1292 reply.ip1 =
lt->getPeerIpAdr(link);
1294 reply.port1 =
lt->getPeerPort(link);
1295 reply.adr1 =
lt->getPeerAdr(link);
1296 reply.rspec1 =
lt->getRates(link);
1297 reply.
rspec2 =
lt->getAvailRates(link);
1300 reply.
errMsg =
"get link: invalid link number";
1301 reply.
mode = CtlPkt::NEG_REPLY;
1308 reply.
errMsg =
"get link: invalid link number";
1309 reply.
mode = CtlPkt::NEG_REPLY;
1313 int iface =
lt->getIface(link);
1314 if (cp.rspec1.isSet()) {
1319 if (!delta.
leq(ifAvail)) {
1321 reply.
errMsg =
"mod link: request "
1323 "exceeds interface capacity";
1324 reply.
mode = CtlPkt::NEG_REPLY;
1328 linkRates = cp.rspec1;
1329 qm->setLinkRates(link,cp.rspec1);
1330 cp.rspec1.
scale(.9);
1331 lt->getAvailRates(link) = cp.rspec1;
1336 bool RouterCore::addComtree(
CtlPkt& cp,
CtlPkt& reply) {
1340 reply.
errMsg =
"add comtree: cannot add comtree";
1341 reply.
mode = CtlPkt::NEG_REPLY;
1345 bool RouterCore::dropComtree(
CtlPkt& cp,
CtlPkt& reply) {
1353 rt->purgeRoutes(comt);
1359 set<int>::iterator pp;
1360 int *clnks =
new int[linkSet.size()];
int i = 0;
1361 for (pp = linkSet.begin(); pp != linkSet.end(); pp++) clnks[i++] = *pp;
1363 dropComtreeLink(ctx,
ctt->
getLink(clnks[i]),clnks[i]);
1371 bool RouterCore::getComtree(
CtlPkt& cp,
CtlPkt& reply) {
1375 reply.
errMsg =
"get comtree: invalid comtree";
1376 reply.
mode = CtlPkt::NEG_REPLY;
1386 bool RouterCore::modComtree(
CtlPkt& cp,
CtlPkt& reply) {
1394 if (plnk != 0 && !
ctt->
isLink(ctx,plnk)) {
1395 reply.
errMsg =
"specified link does "
1396 "not belong to comtree";
1397 reply.
mode = CtlPkt::NEG_REPLY;
1401 reply.
errMsg =
"specified link does "
1402 "not connect to a router";
1403 reply.
mode = CtlPkt::NEG_REPLY;
1410 reply.
errMsg =
"modify comtree: invalid comtree";
1411 reply.
mode = CtlPkt::NEG_REPLY;
1415 bool RouterCore::addComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1419 reply.
errMsg =
"add comtree link: invalid comtree";
1420 reply.
mode = CtlPkt::NEG_REPLY;
1426 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1427 lnk =
lt->
lookup(cp.ip1, cp.port1);
1428 }
else if (cp.adr1 != 0) {
1432 reply.
errMsg =
"add comtree link: invalid link or "
1434 reply.
mode = CtlPkt::NEG_REPLY;
1438 bool isCore =
false;
1441 reply.
errMsg =
"add comtree link: must specify "
1442 "core flag on links to routers";
1443 reply.
mode = CtlPkt::NEG_REPLY;
1455 reply.
errMsg =
"add comtree link: specified "
1456 "link already in comtree";
1457 reply.
mode = CtlPkt::NEG_REPLY;
1463 reply.
errMsg =
"add comtree link: cannot add "
1464 "requested comtree link";
1465 reply.
mode = CtlPkt::NEG_REPLY;
1472 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1474 int rtx =
rt->getRteIndex(comt,peerAdr);
1475 if (rtx == 0)
rt->addEntry(comt,peerAdr,cLnk);
1480 int rtx =
rt->getRteIndex(comt,dest);
1481 if (rtx == 0)
rt->addEntry(comt,dest,cLnk);
1489 reply.
errMsg =
"add comtree link: no queues "
1490 "available for link";
1491 reply.
mode = CtlPkt::NEG_REPLY;
1499 if (!minRates.leq(
lt->getAvailRates(lnk))) {
1500 reply.
errMsg =
"add comtree link: request "
1501 "exceeds link capacity";
1502 reply.
mode = CtlPkt::NEG_REPLY;
1505 lt->getAvailRates(lnk).subtract(minRates);
1508 qm->setQRates(qid,minRates);
1509 if (isRtr)
qm->setQLimits(qid,500,1000000);
1510 else qm->setQLimits(qid,500,1000000);
1511 sm->clearQuStats(qid);
1516 bool RouterCore::dropComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1520 reply.
errMsg =
"drop comtree link: invalid comtree";
1521 reply.
mode = CtlPkt::NEG_REPLY;
1527 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1528 lnk =
lt->
lookup(cp.ip1, cp.port1);
1529 }
else if (cp.adr1 != 0) {
1533 reply.
errMsg =
"drop comtree link: invalid link "
1534 "or peer IP and port";
1535 reply.
mode = CtlPkt::NEG_REPLY;
1540 dropComtreeLink(ctx,lnk,cLnk);
1545 void RouterCore::dropComtreeLink(
int ctx,
int lnk,
int cLnk) {
1550 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1553 int rtx =
rt->getRteIndex(comt,peerAdr);
1554 if (rtx != 0)
rt->removeEntry(rtx);
1559 int rtx =
rt->getRteIndex(comt,dest);
1560 if (rtx != 0)
rt->removeEntry(rtx);
1570 set<int>::iterator rp;
1571 int *routes =
new int[rteSet.size()];
1573 for (rp = rteSet.begin(); rp != rteSet.end(); rp++) routes[i++] = *rp;
1582 cerr <<
"dropComtreeLink: internal error detected "
1583 "final removeLink failed\n";
1587 bool RouterCore::modComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1591 reply.
errMsg =
"modify comtree link: invalid comtree";
1592 reply.
mode = CtlPkt::NEG_REPLY;
1597 reply.
errMsg =
"modify comtree link: invalid link number";
1598 reply.
mode = CtlPkt::NEG_REPLY;
1603 reply.
errMsg =
"modify comtree link: specified link "
1604 "not defined in specified comtree";
1605 reply.
mode = CtlPkt::NEG_REPLY;
1610 if (!rs.isSet())
return true;
1612 if (!diff.
leq(
lt->getAvailRates(lnk))) {
1613 reply.
errMsg =
"modify comtree link: new rate spec "
1614 "exceeds available link capacity";
1617 lt->getAvailRates(lnk).subtract(diff);
1622 bool RouterCore::getComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1626 reply.
errMsg =
"get comtree link: invalid comtree";
1627 reply.
mode = CtlPkt::NEG_REPLY;
1632 reply.
errMsg =
"get comtree link: invalid link number";
1633 reply.
mode = CtlPkt::NEG_REPLY;
1638 reply.
errMsg =
"get comtree link: specified link "
1639 "not defined in specified comtree";
1640 reply.
mode = CtlPkt::NEG_REPLY;
1655 reply.
errMsg =
"comtree not defined at this router\n";
1656 reply.
mode = CtlPkt::NEG_REPLY;
1661 reply.
errMsg =
"invalid address\n";
1662 reply.
mode = CtlPkt::NEG_REPLY;
1667 int rtx =
rt->getRteIndex(comt,dest);
1673 reply.
errMsg =
"add route: requested route "
1674 "conflicts with existing route";
1675 reply.
mode = CtlPkt::NEG_REPLY;
1678 }
else if (
rt->addEntry(comt, dest, lnk)) {
1681 reply.
errMsg =
"add route: cannot add route";
1682 reply.
mode = CtlPkt::NEG_REPLY;
1686 bool RouterCore::dropRoute(
CtlPkt& cp,
CtlPkt& reply) {
1689 reply.
errMsg =
"comtree not defined at this router\n";
1690 reply.
mode = CtlPkt::NEG_REPLY;
1695 reply.
errMsg =
"invalid address\n";
1696 reply.
mode = CtlPkt::NEG_REPLY;
1699 int rtx =
rt->getRteIndex(comt,dest);
1700 rt->removeEntry(rtx);
1707 reply.
errMsg =
"comtree not defined at this router\n";
1708 reply.
mode = CtlPkt::NEG_REPLY;
1713 reply.
errMsg =
"invalid address\n";
1714 reply.
mode = CtlPkt::NEG_REPLY;
1717 int rtx =
rt->getRteIndex(comt,dest);
1729 reply.
errMsg =
"get route: no route for specified address";
1730 reply.
mode = CtlPkt::NEG_REPLY;
1742 reply.
errMsg =
"comtree not defined at this router\n";
1743 reply.
mode = CtlPkt::NEG_REPLY;
1748 reply.
errMsg =
"invalid address\n";
1749 reply.
mode = CtlPkt::NEG_REPLY;
1752 int rtx =
rt->getRteIndex(comt,dest);
1756 reply.
errMsg =
"modify route: cannot "
1757 "set link in multicast route";
1758 reply.
mode = CtlPkt::NEG_REPLY;
1765 reply.
errMsg =
"modify route: invalid route";
1766 reply.
mode = CtlPkt::NEG_REPLY;
1780 reply.
errMsg =
"attempting to set leaf address range when "
1782 reply.
mode = CtlPkt::NEG_REPLY;
1786 fAdr_t lastLeafAdr = cp.adr2;
1788 reply.
errMsg =
"request contained empty leaf address range";
1789 reply.
mode = CtlPkt::NEG_REPLY;
1803 uint64_t nonce =
lt->getNonce(lnk);
1805 p.
comtree = Forest::CONNECT_COMT;
1807 p.payload()[0] = htonl((
int) (nonce >> 32));
1808 p.payload()[1] = htonl((
int) (nonce & 0xffffffff));
1813 pair<uint64_t,CpInfo> cpp;
1814 cpp.first = 1; cpp.first <<= 63; cpp.first |= nonce;
1815 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
1821 cerr <<
"RouterCore::sendConnect: no packets left in packet "
1825 iop->send(copy,lnk);
1839 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
1846 cp.
mode = CtlPkt::REQUEST;
1849 if (cp.
pack() == 0) {
1850 cerr <<
"RouterCore::sendCpReq: control packet packing error\n";
1861 pair<uint64_t,CpInfo> cpp;
1863 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
1870 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
1890 map<uint64_t,CpInfo>::iterator pp;
1892 if (now < pp->second.timestamp + 1000000000)
continue;
1893 pktx px = pp->second.px;
1895 if (pp->second.nSent >= 3) {
1897 cerr <<
"RouterCore::resendCpReq: received no reply to "
1898 "control packet after three attempts\n"
1905 cout <<
"resending control packet\n" << p.
toString(s1);
1907 pp->second.timestamp =
now;
1911 cerr <<
"RouterCore::resendCpReq: no packets left in "
1917 }
else if (booting) {
1936 map<uint64_t,CpInfo>::iterator pp =
pending->find(cpr.
seqNum);
1949 case CtlPkt::CLIENT_CONNECT:
case CtlPkt::CLIENT_DISCONNECT:
1950 if (cpr.
mode == CtlPkt::NEG_REPLY) {
1951 cerr <<
"RouterCore::handleCpReply: got negative reply "
1952 "to a connect or disconnect request: "
1958 case CtlPkt::BOOT_ROUTER: {
1959 if (cpr.
mode == CtlPkt::NEG_REPLY) {
1960 cerr <<
"RouterCore::handleCpReply: got "
1961 "negative reply to a boot request: "
1965 if (booting && !
setup()) {
1966 cerr <<
"RouterCore::handleCpReply: setup failed after "
1967 "completion of boot phase\n";
1972 iop->closeBootSock();
1977 cerr <<
"RouterCore::handleCpReply: unexpected control packet "
1992 int paylen = cp.
pack();
1994 cerr <<
"RouterCore::returnToSender: control packet formatting "
1995 "error, zero payload length\n";
1998 p.
length = (Packet::OVERHEAD + paylen);