diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-10-28 15:06:43 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-10-28 15:06:43 -0700 |
commit | 3e948fcd9327d85d3a55e35156aa5d56e6793d80 (patch) | |
tree | 8d5877e79b7a19e1b7feb135fb23dbd88aefbd98 | |
parent | 8aa75321e2198506b522caf3b78547d2997c226b (diff) | |
download | infinitytier-3e948fcd9327d85d3a55e35156aa5d56e6793d80.tar.gz infinitytier-3e948fcd9327d85d3a55e35156aa5d56e6793d80.zip |
.... aaaaaaand multicast testnet functionsa are in!
-rw-r--r-- | testnet.cpp | 151 |
1 files changed, 126 insertions, 25 deletions
diff --git a/testnet.cpp b/testnet.cpp index b6f6572b..0d0a7be4 100644 --- a/testnet.cpp +++ b/testnet.cpp @@ -223,8 +223,10 @@ static void doHelp(const std::vector<std::string> &cmd) printf("---------- leave <address/*/**> <network ID>"ZT_EOL_S); printf("---------- listnetworks <address/*/**>"ZT_EOL_S); printf("---------- listpeers <address/*/**>"ZT_EOL_S); - printf("---------- unicast <address/*/**> <address/*/**> <network ID> <frame length, min: 16> [<timeout, default: 2>]"ZT_EOL_S); + printf("---------- unicast <address/*/**> <address/*/**> <network ID> <frame length, min: 16> [<timeout (sec)>]"ZT_EOL_S); + printf("---------- multicast <address/*/**> <MAC/*> <network ID> <frame length, min: 16> [<timeout (sec)>]"ZT_EOL_S); printf("---------- quit"ZT_EOL_S); + printf("---------- . runs previous command again"ZT_EOL_S); } static void doMKSN(const std::vector<std::string> &cmd) @@ -577,6 +579,91 @@ static void doUnicast(const std::vector<std::string> &cmd) printf("---------- sent %u, received %u"ZT_EOL_S,(unsigned int)sentPairs.size(),(unsigned int)receivedPairs.size()); } +static void doMulticast(const std::vector<std::string> &cmd) +{ + union { + uint64_t i[2]; + unsigned char data[2800]; + } pkt; + + if (cmd.size() < 5) { + doHelp(cmd); + return; + } + + uint64_t nwid = Utils::hexStrToU64(cmd[3].c_str()); + unsigned int frameLen = Utils::strToUInt(cmd[4].c_str()); + uint64_t tout = 2000; + if (cmd.size() >= 6) + tout = Utils::strToU64(cmd[5].c_str()) * 1000ULL; + + if (frameLen < 16) + frameLen = 16; + if (frameLen > 2800) + frameLen = 2800; + + std::vector<Address> senders; + if ((cmd[1] == "*")||(cmd[1] == "**")) { + bool includeSuper = (cmd[1] == "**"); + for(std::map< Address,SimNode * >::iterator n(nodes.begin());n!=nodes.end();++n) { + if ((includeSuper)||(!n->second->supernode)) + senders.push_back(n->first); + } + } else senders.push_back(Address(cmd[1])); + + MAC mcaddr; + if (cmd[2] == "*") + mcaddr = MAC(0xff,0xff,0xff,0xff,0xff,0xff); + else mcaddr.fromString(cmd[2].c_str()); + + if (!mcaddr.isMulticast()) { + printf("---------- %s is not a multicast MAC address"ZT_EOL_S,mcaddr.toString().c_str()); + return; + } + + for(unsigned int i=0;i<frameLen;++i) + pkt.data[i] = (unsigned char)prng.next32(); + + for(std::vector<Address>::iterator s(senders.begin());s!=senders.end();++s) { + SimNode *sender = nodes[*s]; + SharedPtr<TestEthernetTap> stap(sender->tapFactory.getByNwid(nwid)); + if (stap) { + pkt.i[0] = s->toInt(); + pkt.i[1] = Utils::now(); + stap->injectPacketFromHost(stap->mac(),mcaddr,0xdead,pkt.data,frameLen); + printf("%s -> %s etherType 0xdead network %.16llx length %u"ZT_EOL_S,s->toString().c_str(),mcaddr.toString().c_str(),nwid,frameLen); + } else { + printf("%s -> !%s (sender is not a member of %.16llx)"ZT_EOL_S,s->toString().c_str(),mcaddr.toString().c_str(),nwid); + } + } + + printf("---------- waiting %llu seconds..."ZT_EOL_S,tout / 1000ULL); + + uint64_t toutend = Utils::now() + tout; + unsigned int receiveCount = 0; + TestEthernetTap::TestFrame frame; + do { + for(std::map< Address,SimNode * >::iterator nn(nodes.begin());nn!=nodes.end();++nn) { + SimNode *receiver = nn->second; + SharedPtr<TestEthernetTap> rtap(receiver->tapFactory.getByNwid(nwid)); + if (rtap) { + while (rtap->getNextReceivedFrame(frame,1)) { + if ((frame.len == frameLen)&&(!memcmp(frame.data + 16,pkt.data + 16,frameLen - 16))) { + uint64_t ints[2]; + memcpy(ints,frame.data,16); + printf("%s <- %.10llx received test packet, latency == %llums"ZT_EOL_S,nn->first.toString().c_str(),ints[0],frame.timestamp - ints[1]); + ++receiveCount; + } else { + printf("%s !! got spurious packet, length == %u, etherType == 0x%.4x"ZT_EOL_S,nn->first.toString().c_str(),frame.len,frame.etherType); + } + } + } + } + } while (Utils::now() < toutend); + + printf("---------- test multicast received by %u peers"ZT_EOL_S,receiveCount); +} + int main(int argc,char **argv) { char linebuf[1024]; @@ -616,36 +703,50 @@ int main(int argc,char **argv) printf("Type 'help' for help."ZT_EOL_S); printf(ZT_EOL_S); - for(;;) { + std::vector<std::string> cmd,prevCmd; + bool run = true; + while (run) { printf(">> "); fflush(stdout); if (!fgets(linebuf,sizeof(linebuf),stdin)) break; - std::vector<std::string> cmd(Utils::split(linebuf," \r\n\t","\\","\"")); - if (cmd.size() == 0) - continue; - if (cmd[0] == "quit") + cmd = Utils::split(linebuf," \r\n\t","\\","\""); + + for(;;) { + if (cmd.size() == 0) + break; + else if (cmd[0] == "quit") + run = false; + else if (cmd[0] == "help") + doHelp(cmd); + else if (cmd[0] == "mksn") + doMKSN(cmd); + else if (cmd[0] == "mkn") + doMKN(cmd); + else if (cmd[0] == "list") + doList(cmd); + else if (cmd[0] == "join") + doJoin(cmd); + else if (cmd[0] == "leave") + doLeave(cmd); + else if (cmd[0] == "listnetworks") + doListNetworks(cmd); + else if (cmd[0] == "listpeers") + doListPeers(cmd); + else if (cmd[0] == "unicast") + doUnicast(cmd); + else if (cmd[0] == "multicast") + doMulticast(cmd); + else if ((cmd[0] == ".")&&(prevCmd.size() > 0)) { + cmd = prevCmd; + continue; + } else doHelp(cmd); break; - else if (cmd[0] == "help") - doHelp(cmd); - else if (cmd[0] == "mksn") - doMKSN(cmd); - else if (cmd[0] == "mkn") - doMKN(cmd); - else if (cmd[0] == "list") - doList(cmd); - else if (cmd[0] == "join") - doJoin(cmd); - else if (cmd[0] == "leave") - doLeave(cmd); - else if (cmd[0] == "listnetworks") - doListNetworks(cmd); - else if (cmd[0] == "listpeers") - doListPeers(cmd); - else if (cmd[0] == "unicast") - doUnicast(cmd); - else doHelp(cmd); + } + + if ((cmd.size() > 0)&&(cmd[0] != ".")) + prevCmd = cmd; } for(std::map< Address,SimNode * >::iterator n(nodes.begin());n!=nodes.end();++n) { |