diff --git a/pelab/magent/UDP/README_UDP.txt b/pelab/magent/UDP/README_UDP.txt new file mode 100644 index 0000000000000000000000000000000000000000..89c6f7d0100694e95403623705affe409100f21b --- /dev/null +++ b/pelab/magent/UDP/README_UDP.txt @@ -0,0 +1,53 @@ + ACIM for UDP applications + ------------------------- + +Contact: pramod@cs.utah.edu + +Overview: +--------- + +UDP for Flexlab is implemented as two stand alone programs as of now - +it will soon be integrated into the exisiting Magent code. + +The client applications sends UDP packets to the server at a specified rate. The +client records a timestamp for each packet sent and for each ACK received. The +server sends acknowledgements ( with some redundancy built in ) back to the client. + +Based on the time taken for these acks to get back, since the original packets were +sent out: the client calculates the RTT, +the minimum delay ( which is interpreted as all delay except queuing ) ,the maximum +queuing delay, and the achieved throughput. + +It has been tested in Emulab, with background cross traffic generated by IPerf TCP and +UDP sessions. I will check in the resulting throughput graphs soon. + +How to run it: +-------------- + +Start the server program first: + +1) cd to 'UdpServerDir' +2) Type 'make -f Makefile.server' +3) ./runServer.sh + +Then start the client app ( on a different host ): + +1) cd to 'UdpClientDir' +2) Type 'make -f Makefile.client' +3) ./runClient.sh + +Depending on the arguments given in 'runClient.sh', the client app sends +some number of UDP packets to the server and calculates the achieved throughput values. + +The client runs in an infinite loop and (as of now) does not terminate on its own, so +kill it after it stops printing to stdout. + +4) Then type './showTputGraph.sh' in 'UdpClientDir'. This displayes a graph +of the throughput values for the session. ( Make sure that gnuplot is present on the system ). + + +Results and graphs: +------------------ + +Coming soon. + diff --git a/pelab/magent/UDP/UdpClientDir/Makefile.Client b/pelab/magent/UDP/UdpClientDir/Makefile.Client new file mode 100644 index 0000000000000000000000000000000000000000..48c2e2259da525ad8b49d90355d6f77dfcca3a8e --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/Makefile.Client @@ -0,0 +1,45 @@ +EXECUTABLE=UdpClient +CC=g++ -g +CFLAGS= + +COMPILE_DIR=.OBJECTS + +OBJECTS=${COMPILE_DIR}/UdpClient.o \ + ${COMPILE_DIR}/UdpPacketSensor.o \ + ${COMPILE_DIR}/UdpMinDelaySensor.o \ + ${COMPILE_DIR}/UdpMaxDelaySensor.o \ + ${COMPILE_DIR}/UdpThroughputSensor.o \ + ${COMPILE_DIR}/UdpPacketInfo.o \ + ${COMPILE_DIR}/UdpSensor.o + + +COMMON_INCLUDES=UdpLibs.h \ + UdpState.h + +${EXECUTABLE}: ${OBJECTS} + ${CC} -o $@ ${CFLAGS} $+ -lpcap + +${COMPILE_DIR}/UdpClient.o: UdpClient.cc UdpPacketSensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpMinDelaySensor.o: UdpMinDelaySensor.cc UdpMinDelaySensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpMaxDelaySensor.o: UdpMaxDelaySensor.cc UdpMaxDelaySensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpThroughputSensor.o: UdpThroughputSensor.cc UdpThroughputSensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpPacketSensor.o: UdpPacketSensor.cc UdpPacketSensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpPacketInfo.o: UdpPacketInfo.cc UdpPacketInfo.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +${COMPILE_DIR}/UdpSensor.o: UdpSensor.cc UdpSensor.h ${COMMON_INCLUDES} + ${CC} -c ${CFLAGS} -o $@ $< + +clean: + rm -f ${COMPILE_DIR}/*.o ${EXECUTABLE} + diff --git a/pelab/magent/UDP/UdpClientDir/Output.log b/pelab/magent/UDP/UdpClientDir/Output.log new file mode 100644 index 0000000000000000000000000000000000000000..5fe94c608854fc260d609f8fd68ef3d51b1f2a0e --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/Output.log @@ -0,0 +1,802 @@ +0 215219.2 +2595 215219.2 +5286 215219.2 +7979 215219.2 +10575 215219.2 +13275 215219.2 +15958 215219.2 +18553 215219.2 +21251 215219.2 +23936 215219.2 +26530 215219.2 +29222 215219.2 +31911 215219.2 +34507 215219.2 +37198 215219.2 +39892 215219.2 +42487 215219.2 +45180 215219.2 +47875 215219.2 +50468 215219.2 +53157 215219.2 +55853 215219.2 +58445 215219.2 +61135 215219.2 +63828 215219.2 +66423 215219.2 +69113 215219.2 +71806 215219.2 +74402 215219.2 +77093 215219.2 +79786 215219.2 +82381 215219.2 +85071 215219.2 +87764 215219.2 +90360 215219.2 +93048 215219.2 +95753 215219.2 +98338 215219.2 +101028 215219.2 +103737 215219.2 +106316 215219.2 +109007 215219.2 +111698 215219.2 +114295 215219.2 +116985 215219.2 +119677 215219.2 +122278 215219.2 +124966 215219.2 +127655 215219.2 +130253 215219.2 +132943 215219.2 +135636 215219.2 +138230 215219.2 +140919 215219.2 +143612 215219.2 +146209 215219.2 +148898 215219.2 +151592 215219.2 +154190 215219.2 +156877 215219.2 +159571 215219.2 +162166 215219.2 +164856 215219.2 +167549 215219.2 +170155 215219.2 +172835 215219.2 +175528 215219.2 +178123 215219.2 +180815 215219.2 +183506 215219.2 +186101 215219.2 +188790 215219.2 +191485 215219.2 +194079 215219.2 +196772 215219.2 +199462 215219.2 +202059 215219.2 +204755 215219.2 +207443 215219.2 +210037 215219.2 +212728 215219.2 +215431 215219.2 +218015 215219.2 +220707 215219.2 +223398 215219.2 +225995 215219.2 +228683 215219.2 +231379 215219.2 +233973 215219.2 +236663 215219.2 +239354 215219.2 +241953 215219.2 +244642 215219.2 +247334 215219.2 +249929 215219.2 +252633 215219.2 +255312 215219.2 +257908 215219.2 +260607 215219.2 +263291 215219.2 +265887 215219.2 +268579 215219.2 +271269 215219.2 +273865 215219.2 +276556 215219.2 +279248 215219.2 +281845 215219.2 +284533 215219.2 +287229 215219.2 +289822 215219.2 +292512 215219.2 +295211 215219.2 +297801 215219.2 +300491 215219.2 +303184 215219.2 +305781 215219.2 +308469 215219.2 +311164 215219.2 +313759 215219.2 +316449 215219.2 +319141 215219.2 +321739 215219.2 +324427 215219.2 +327120 215219.2 +329715 215219.2 +332415 215219.2 +335110 215219.2 +337694 215219.2 +340385 215219.2 +343076 215219.2 +345673 215219.2 +348363 215219.2 +351055 215219.2 +353652 215219.2 +356341 215219.2 +359032 215219.2 +361634 215219.2 +364318 215219.2 +367013 215219.2 +369609 215219.2 +372298 215219.2 +374990 215219.2 +377587 215219.2 +380275 215219.2 +382970 215219.2 +385566 215219.2 +388255 215219.2 +390949 215219.2 +393544 215219.2 +396234 215219.2 +398927 215219.2 +401529 215219.2 +404210 215219.2 +406906 215219.2 +409516 215219.2 +412192 215219.2 +414884 215219.2 +417482 215219.2 +420170 215219.2 +422861 215219.2 +425457 215219.2 +428147 215219.2 +430840 215219.2 +433437 215219.2 +436126 215219.2 +438820 215219.2 +441416 215219.2 +444108 215219.2 +446799 215219.2 +449395 215219.2 +452089 215219.2 +454778 215219.2 +457371 215219.2 +460062 215219.2 +462754 215219.2 +465350 215219.2 +468041 215219.2 +470732 215219.2 +473329 215219.2 +476018 215219.2 +478712 215219.2 +481307 215219.2 +484004 215219.2 +486692 215219.2 +489283 215219.2 +491993 215219.2 +494669 215219.2 +497265 215219.2 +499956 215219.2 +502648 215219.2 +505244 215219.2 +507933 215219.2 +510626 215219.2 +513221 215219.2 +515911 215219.2 +518606 215219.2 +521200 215219.2 +523890 215219.2 +526586 14378.624 +529178 14529.92 +531867 14529.92 +534563 14385.024 +537158 14534.144 +539846 14534.144 +542540 14391.808 +545134 14541.44 +547827 14541.44 +550518 14398.848 +553114 14547.968 +555804 14547.968 +558498 14405.376 +561093 14554.88 +563784 14554.88 +566480 14411.648 +569071 14561.92 +571762 14561.92 +574466 14417.792 +577048 14569.088 +579740 14569.088 +582431 14425.856 +585029 14575.616 +587718 14575.616 +590411 14575.616 +593010 14372.224 +595697 14510.976 +598389 14510.976 +600990 14378.752 +603676 14521.088 +606370 14521.088 +608965 14388.096 +611654 14527.744 +614346 14527.744 +616941 14395.52 +619633 14534.912 +622325 14534.912 +624920 14402.048 +627611 14541.696 +630303 14541.696 +632899 14408.704 +635590 14548.224 +638283 14548.224 +640890 14414.336 +643570 14555.136 +646261 14555.136 +648865 14421.504 +651547 14562.304 +654240 14562.304 +656836 14429.184 +659526 14569.472 +662220 14569.472 +664814 14436.224 +667503 14576.512 +670198 14576.512 +672791 14576.512 +675487 14372.992 +678176 14511.36 +680772 14511.36 +683467 14379.776 +686154 14519.808 +688751 14519.808 +691442 14387.456 +694132 14526.976 +696733 14526.976 +699420 14394.24 +702110 14533.888 +704707 14533.888 +707396 14401.28 +710089 14540.672 +712685 14540.672 +715375 14407.936 +718067 14547.2 +720664 14547.2 +723364 14413.44 +726046 14554.368 +728642 14554.368 +731346 14420.096 +734025 14561.28 +736621 14561.28 +739312 14428.416 +742005 14568.064 +744599 14568.064 +747289 14435.2 +749981 14575.488 +752578 14575.488 +755268 14575.488 +757961 14372.48 +760557 14520.576 +763245 14520.576 +765945 14378.624 +768535 14529.664 +771224 14529.664 +773917 14388.736 +776513 14537.472 +779207 14537.472 +781896 14394.88 +784493 14544.128 +787181 14544.128 +789874 14401.664 +792470 14551.296 +795162 14551.296 +797851 14408.704 +800450 14558.08 +803138 14558.08 +805846 14413.952 +808426 14565.76 +811116 14565.76 +813817 14421.504 +816406 14572.288 +819095 14572.288 +821790 14429.184 +824384 14579.712 +827074 14579.712 +829767 14579.712 +832368 14376.32 +835053 14515.2 +837746 14515.2 +840344 14383.744 +843030 14522.88 +845723 14522.88 +848327 14389.504 +851010 14529.664 +853702 14529.664 +856298 14397.312 +858988 14537.088 +861689 14537.088 +864277 14404.352 +866968 14544.128 +869660 14544.128 +872255 14411.648 +874946 14551.168 +877640 14551.168 +880245 14417.152 +882924 14558.592 +885618 14558.592 +888214 14425.088 +890903 14565.12 +893596 14565.12 +896190 14432.128 +898880 14572.288 +901575 14572.288 +904169 14438.784 +906858 14579.072 +909555 14579.072 +912149 14579.072 +914843 14375.552 +917532 14513.92 +920129 14513.92 +922818 14382.464 +925510 14522.368 +928105 14522.368 +930795 14390.4 +933488 14529.408 +936084 14529.408 +938775 14397.184 +941468 14537.6 +944064 14537.6 +946752 14405.248 +949446 14544.384 +952041 14544.384 +954730 14411.776 +957425 14550.912 +960019 14550.912 +962721 14417.024 +965402 14558.336 +967998 14558.336 +970695 14424.448 +973381 14564.864 +975976 14564.864 +978666 14431.872 +981359 14571.904 +983956 14571.904 +986646 14438.4 +989338 14578.432 +991935 14578.432 +994625 14578.432 +997322 14374.912 +999912 14523.392 +1002602 14523.392 +1005303 14381.056 +1007890 14532.864 +1010580 14532.864 +1013275 14390.144 +1015868 14539.776 +1018562 14539.776 +1021254 14396.928 +1023848 14546.688 +1026537 14546.688 +1029228 14404.608 +1031827 14553.728 +1034516 14553.728 +1037209 14411.008 +1039806 14560.384 +1042495 14560.384 +1045198 14416.64 +1047783 14567.552 +1050474 14567.552 +1053181 14422.784 +1055761 14574.336 +1058454 14574.336 +1061145 14574.336 +1063742 14371.2 +1066432 14509.312 +1069122 14509.312 +1071726 14377.344 +1074408 14518.912 +1077102 14518.912 +1079699 14384.0 +1082388 14523.52 +1085080 14523.52 +1087678 14390.784 +1090366 14530.688 +1093060 14530.688 +1095653 14397.952 +1098344 14537.472 +1101045 14537.472 +1103634 14404.352 +1106324 14544.384 +1109016 14544.384 +1111611 14411.392 +1114302 14552.192 +1116996 14552.192 +1119603 14417.792 +1122279 14559.104 +1124973 14559.104 +1127571 14425.728 +1130271 14564.608 +1132953 14564.608 +1135547 14432.768 +1138239 14572.416 +1140930 14572.416 +1143527 14439.424 +1146215 14579.84 +1148908 14579.84 +1151503 14579.84 +1154198 14375.936 +1156886 14514.176 +1159485 14514.176 +1162174 14382.72 +1164867 14522.368 +1167460 14522.368 +1170153 14390.144 +1172845 14529.28 +1175440 14529.28 +1178129 14397.184 +1180822 14536.448 +1183419 14536.448 +1186106 14404.352 +1188801 14543.616 +1191397 14543.616 +1194098 14409.6 +1196780 14550.144 +1199377 14550.144 +1202072 14416.768 +1204759 14556.8 +1207354 14556.8 +1210045 14424.192 +1212737 14564.224 +1215335 14564.224 +1218022 14431.36 +1220716 14571.264 +1223311 14571.264 +1226000 14438.4 +1228697 14577.92 +1231291 14577.92 +1233980 14577.92 +1236679 14374.528 +1239268 14523.52 +1241958 14523.52 +1244652 14381.952 +1247251 14531.968 +1249940 14531.968 +1252735 14379.392 +1255225 14539.776 +1257915 14539.776 +1260608 14396.928 +1263204 14546.56 +1265893 14546.56 +1268587 14403.968 +1271182 14553.472 +1273874 14553.472 +1276576 14409.6 +1279162 14560.384 +1281851 14560.384 +1284563 14416.64 +1287140 14568.448 +1289829 14568.448 +1292525 14425.472 +1295117 14575.872 +1297808 14575.872 +1300500 14575.872 +1303101 14372.48 +1305786 14511.232 +1308479 14511.232 +1311075 14380.032 +1313766 14523.136 +1316458 14523.136 +1319055 14390.528 +1321743 14530.048 +1324437 14530.048 +1327032 14397.312 +1329722 14537.088 +1332417 14537.088 +1335010 14404.352 +1337699 14544.128 +1340394 14544.128 +1342994 14410.624 +1345679 14551.168 +1348372 14551.168 +1350981 14417.024 +1353659 14558.08 +1356353 14558.08 +1358948 14424.832 +1361634 14565.504 +1364329 14565.504 +1366923 14432.128 +1369616 14571.904 +1372308 14571.904 +1374903 14438.528 +1377593 14578.816 +1380286 14578.816 +1382880 14578.816 +1385580 14375.04 +1388263 14514.176 +1390861 14514.176 +1393551 14382.336 +1396244 14522.368 +1398839 14522.368 +1401530 14389.888 +1404225 14528.768 +1406817 14528.768 +1409508 14396.928 +1412200 14536.192 +1414797 14536.192 +1417486 14403.584 +1420178 14542.976 +1422775 14542.976 +1425481 14408.576 +1428157 14550.144 +1430753 14550.144 +1433452 14416.384 +1436137 14557.056 +1438732 14557.056 +1441423 14424.192 +1444114 14565.504 +1446712 14565.504 +1449400 14432.512 +1452094 14572.288 +1454688 14572.288 +1457379 14439.168 +1460075 14578.816 +1462667 14578.816 +1465359 14578.816 +1468055 14375.552 +1470647 14524.16 +1473337 14524.16 +1476029 14382.72 +1478626 14532.992 +1481314 14532.992 +1484007 14390.912 +1486602 14540.416 +1489293 14540.416 +1491985 14397.824 +1494581 14547.584 +1497273 14547.584 +1499964 14405.248 +1502560 14554.496 +1505249 14554.496 +1507954 14410.368 +1510538 14561.536 +1513229 14561.536 +1515939 14416.768 +1518519 14568.448 +1521208 14568.448 +1523900 14425.728 +1526495 14575.872 +1529184 14575.872 +1531879 14575.872 +1534481 14372.224 +1537165 14510.976 +1539856 14510.976 +1542453 14379.648 +1545144 14522.752 +1547835 14522.752 +1550431 14390.528 +1553120 14530.304 +1555814 14530.304 +1558410 14397.568 +1561101 14536.832 +1563796 14536.832 +1566390 14404.224 +1569079 14544.0 +1571771 14544.0 +1574371 14411.264 +1577056 14551.552 +1579751 14551.552 +1582361 14416.768 +1585034 14558.08 +1587728 14558.08 +1590326 14424.704 +1593013 14565.12 +1595708 14565.12 +1598303 14431.744 +1600992 14572.032 +1603687 14572.032 +1606281 14439.552 +1608971 14579.712 +1611665 14579.712 +1614260 14579.712 +1616953 14376.32 +1619642 14514.816 +1622239 14514.816 +1624932 14382.976 +1627622 14522.368 +1630217 14522.368 +1632908 14389.888 +1635600 14529.28 +1638197 14529.28 +1640884 14397.184 +1643579 14535.808 +1646182 14535.808 +1648863 14403.584 +1651557 14543.104 +1654153 14543.104 +1656854 14409.344 +1659536 14549.888 +1662133 14549.888 +1664830 14416.384 +1667517 14556.8 +1670110 14556.8 +1672800 14424.448 +1675491 14564.608 +1678088 14564.608 +1680777 14431.744 +1683471 14571.648 +1686066 14571.648 +1688758 14438.528 +1691452 14578.432 +1694044 14578.432 +1696737 14578.432 +1699434 14375.04 +1702023 14524.032 +1704715 14524.032 +1707406 14382.976 +1710001 14532.992 +1712697 14532.992 +1715385 14391.552 +1717980 14540.16 +1720671 14540.16 +1723364 14397.312 +1725959 14547.2 +1728649 14547.2 +1731342 14404.352 +1733938 14553.856 +1736627 14553.856 +1739334 14409.6 +1741917 14560.64 +1744607 14560.64 +1747303 14417.024 +1749894 14567.424 +1752585 14567.424 +1755278 14424.192 +1757872 14574.208 +1760563 14574.208 +1763257 14430.72 +1765855 14580.48 +1768543 14580.48 +1771234 14580.48 +1773832 14379.008 +1776522 14522.752 +1779213 14522.752 +1781809 14390.144 +1784500 14529.92 +1787190 14529.92 +1789787 14397.312 +1792475 14537.216 +1795171 14537.216 +1797767 14404.224 +1800457 14544.0 +1803153 14544.0 +1805751 14410.624 +1808435 14550.784 +1811129 14550.784 +1813740 14416.0 +1816411 14558.08 +1819107 14558.08 +1821704 14424.704 +1824391 14565.248 +1827084 14565.248 +1829679 14431.872 +1832369 14572.288 +1835063 14572.288 +1837657 14439.168 +1840349 14579.2 +1843042 14579.2 +1845637 14579.2 +1848334 14375.68 +1851020 14514.176 +1853616 14514.176 +1856306 14382.976 +1858998 14522.752 +1861593 14522.752 +1864285 14390.4 +1866976 14529.408 +1869573 14529.408 +1872263 14397.184 +1874955 14536.576 +1877553 14536.576 +1880242 14404.352 +1882936 14543.616 +1885531 14543.616 +1888231 14409.984 +1890914 14550.528 +1893509 14550.528 +1896207 14417.024 +1898891 14557.952 +1901487 14557.952 +1904178 14425.088 +1906869 14565.12 +1909466 14565.12 +1912155 14432.128 +1914848 14571.904 +1917444 14571.904 +1920136 14438.528 +1922830 14578.56 +1925422 14578.56 +1928126 14578.56 +1930812 14375.04 +1933401 14527.104 +1936090 14527.104 +1938784 14383.488 +1941380 14533.248 +1944070 14533.248 +1946763 14390.784 +1949360 14540.16 +1952047 14540.16 +1954741 14397.824 +1957337 14547.584 +1960026 14547.584 +1962720 14404.736 +1965317 14554.752 +1968004 14554.752 +1970709 14411.008 +1973294 14561.664 +1975984 14561.664 +1978684 14418.304 +1981273 14568.704 +1983964 14568.704 +1986655 14425.728 +1989251 14575.872 +1991943 14575.872 +1994635 14575.872 +1997237 14372.224 +1999919 14511.232 +2002613 14511.232 +2005208 14379.776 +2007897 14523.52 +2010590 14523.52 +2013187 14390.784 +2015877 14530.048 +2018568 14530.048 +2021166 14397.312 +2023854 14537.216 +2026548 14537.216 +2029142 14404.736 +2031834 14544.384 +2034527 14544.384 +2037123 14411.648 +2039812 14551.552 +2042507 14551.552 +2045110 14417.664 +2047790 14558.592 +2050483 14558.592 +2053078 14425.728 +2055769 14565.504 +2058461 14565.504 +2061057 14432.128 +2063749 14572.288 +2066440 14572.288 +2069035 14439.424 +2071728 14579.456 +2074419 14579.456 +2077015 14579.456 +2079703 14376.96 +2082397 14514.944 +2084993 14514.944 +2087682 14384.128 +2090377 14522.112 +2092972 14522.112 +2095661 14391.424 +2098357 14530.304 +2100950 14530.304 +2103640 14398.336 +2106334 14538.112 +2108929 14538.112 +2111619 14405.376 +2114313 14544.768 +2116909 14544.768 +2119597 14412.288 +2122290 14551.936 +2124886 14551.936 +2127576 14419.456 +2130267 14559.36 diff --git a/pelab/magent/UDP/UdpClientDir/Throughput.log b/pelab/magent/UDP/UdpClientDir/Throughput.log new file mode 100644 index 0000000000000000000000000000000000000000..a23e16cf56a49f0164bd82f80f32b325bef2cc58 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/Throughput.log @@ -0,0 +1,802 @@ +TIME=1167872504410339,TENTATIVE=1681.4 +TIME=1167872504412934,TENTATIVE=1314.52 +TIME=1167872504415625,TENTATIVE=1243.46 +TIME=1167872504418318,TENTATIVE=1179.87 +TIME=1167872504420914,TENTATIVE=1130.06 +TIME=1167872504423614,TENTATIVE=1076.55 +TIME=1167872504426297,TENTATIVE=1029.5 +TIME=1167872504428892,TENTATIVE=991.499 +TIME=1167872504431590,TENTATIVE=950.297 +TIME=1167872504434275,TENTATIVE=912.595 +TIME=1167872504436869,TENTATIVE=883.007 +TIME=1167872504439561,TENTATIVE=850.363 +TIME=1167872504442250,TENTATIVE=820.219 +TIME=1167872504444846,TENTATIVE=795.674 +TIME=1167872504447537,TENTATIVE=769.448 +TIME=1167872504450231,TENTATIVE=744.401 +TIME=1167872504452826,TENTATIVE=724.328 +TIME=1167872504455519,TENTATIVE=702.027 +TIME=1167872504458214,TENTATIVE=681.413 +TIME=1167872504460807,TENTATIVE=664.612 +TIME=1167872504463496,TENTATIVE=646.055 +TIME=1167872504466192,TENTATIVE=628.204 +TIME=1167872504468784,TENTATIVE=614.136 +TIME=1167872504471474,TENTATIVE=598.212 +TIME=1167872504474167,TENTATIVE=583.048 +TIME=1167872504476762,TENTATIVE=570.579 +TIME=1167872504479452,TENTATIVE=556.926 +TIME=1167872504482145,TENTATIVE=543.761 +TIME=1167872504484741,TENTATIVE=532.972 +TIME=1167872504487432,TENTATIVE=520.833 +TIME=1167872504490125,TENTATIVE=509.401 +TIME=1167872504492720,TENTATIVE=499.952 +TIME=1167872504495410,TENTATIVE=489.347 +TIME=1167872504498103,TENTATIVE=479.095 +TIME=1167872504500699,TENTATIVE=470.757 +TIME=1167872504503387,TENTATIVE=461.397 +TIME=1167872504506092,TENTATIVE=452.168 +TIME=1167872504508677,TENTATIVE=444.733 +TIME=1167872504511367,TENTATIVE=436.394 +TIME=1167872504514076,TENTATIVE=428.082 +TIME=1167872504516655,TENTATIVE=421.571 +TIME=1167872504519346,TENTATIVE=413.94 +TIME=1167872504522037,TENTATIVE=406.686 +TIME=1167872504524634,TENTATIVE=400.6 +TIME=1167872504527324,TENTATIVE=393.822 +TIME=1167872504530016,TENTATIVE=387.193 +TIME=1167872504532617,TENTATIVE=381.58 +TIME=1167872504535305,TENTATIVE=375.461 +TIME=1167872504537994,TENTATIVE=369.483 +TIME=1167872504540592,TENTATIVE=364.419 +TIME=1167872504543282,TENTATIVE=358.735 +TIME=1167872504545975,TENTATIVE=353.274 +TIME=1167872504548569,TENTATIVE=348.72 +TIME=1167872504551258,TENTATIVE=343.542 +TIME=1167872504553951,TENTATIVE=338.457 +TIME=1167872504556548,TENTATIVE=334.274 +TIME=1167872504559237,TENTATIVE=329.514 +TIME=1167872504561931,TENTATIVE=324.833 +TIME=1167872504564529,TENTATIVE=320.9 +TIME=1167872504567216,TENTATIVE=316.574 +TIME=1167872504569910,TENTATIVE=312.264 +TIME=1167872504572505,TENTATIVE=308.675 +TIME=1167872504575195,TENTATIVE=304.588 +TIME=1167872504577888,TENTATIVE=300.642 +TIME=1167872504580494,TENTATIVE=297.247 +TIME=1167872504583174,TENTATIVE=293.521 +TIME=1167872504585867,TENTATIVE=289.79 +TIME=1167872504588462,TENTATIVE=286.739 +TIME=1167872504591154,TENTATIVE=283.209 +TIME=1167872504593845,TENTATIVE=279.774 +TIME=1167872504596440,TENTATIVE=276.92 +TIME=1167872504599129,TENTATIVE=273.654 +TIME=1167872504601824,TENTATIVE=270.428 +TIME=1167872504604418,TENTATIVE=267.741 +TIME=1167872504607111,TENTATIVE=264.634 +TIME=1167872504609801,TENTATIVE=261.659 +TIME=1167872504612398,TENTATIVE=259.135 +TIME=1167872504615094,TENTATIVE=256.231 +TIME=1167872504617782,TENTATIVE=253.4 +TIME=1167872504620376,TENTATIVE=251.064 +TIME=1167872504623067,TENTATIVE=248.354 +TIME=1167872504625770,TENTATIVE=245.662 +TIME=1167872504628354,TENTATIVE=243.459 +TIME=1167872504631046,TENTATIVE=240.931 +TIME=1167872504633737,TENTATIVE=238.434 +TIME=1167872504636334,TENTATIVE=236.386 +TIME=1167872504639022,TENTATIVE=233.988 +TIME=1167872504641718,TENTATIVE=231.605 +TIME=1167872504644312,TENTATIVE=229.658 +TIME=1167872504647002,TENTATIVE=227.395 +TIME=1167872504649693,TENTATIVE=225.169 +TIME=1167872504652292,TENTATIVE=223.265 +TIME=1167872504654981,TENTATIVE=221.156 +TIME=1167872504657673,TENTATIVE=219.044 +TIME=1167872504660268,TENTATIVE=217.278 +TIME=1167872504662972,TENTATIVE=215.198 +TIME=1167872504665651,TENTATIVE=213.261 +TIME=1167872504668247,TENTATIVE=211.582 +TIME=1167872504670946,TENTATIVE=209.625 +TIME=1167872504673630,TENTATIVE=207.743 +TIME=1167872504676226,TENTATIVE=206.159 +TIME=1167872504678918,TENTATIVE=204.328 +TIME=1167872504681608,TENTATIVE=202.534 +TIME=1167872504684204,TENTATIVE=201.008 +TIME=1167872504686895,TENTATIVE=199.287 +TIME=1167872504689587,TENTATIVE=197.581 +TIME=1167872504692184,TENTATIVE=196.128 +TIME=1167872504694872,TENTATIVE=194.475 +TIME=1167872504697568,TENTATIVE=192.859 +TIME=1167872504700161,TENTATIVE=191.493 +TIME=1167872504702851,TENTATIVE=189.912 +TIME=1167872504705550,TENTATIVE=188.33 +TIME=1167872504708140,TENTATIVE=187.05 +TIME=1167872504710830,TENTATIVE=185.55 +TIME=1167872504713523,TENTATIVE=184.061 +TIME=1167872504716120,TENTATIVE=182.787 +TIME=1167872504718808,TENTATIVE=181.375 +TIME=1167872504721503,TENTATIVE=179.956 +TIME=1167872504724098,TENTATIVE=178.799 +TIME=1167872504726788,TENTATIVE=177.376 +TIME=1167872504729480,TENTATIVE=176.015 +TIME=1167872504732078,TENTATIVE=174.877 +TIME=1167872504734766,TENTATIVE=173.565 +TIME=1167872504737459,TENTATIVE=172.269 +TIME=1167872504740054,TENTATIVE=171.156 +TIME=1167872504742754,TENTATIVE=169.896 +TIME=1167872504745449,TENTATIVE=168.65 +TIME=1167872504748033,TENTATIVE=167.619 +TIME=1167872504750724,TENTATIVE=166.4 +TIME=1167872504753415,TENTATIVE=165.215 +TIME=1167872504756012,TENTATIVE=164.205 +TIME=1167872504758702,TENTATIVE=163.048 +TIME=1167872504761394,TENTATIVE=161.89 +TIME=1167872504763991,TENTATIVE=160.927 +TIME=1167872504766680,TENTATIVE=159.816 +TIME=1167872504769371,TENTATIVE=158.713 +TIME=1167872504771973,TENTATIVE=157.762 +TIME=1167872504774657,TENTATIVE=156.712 +TIME=1167872504777352,TENTATIVE=155.648 +TIME=1167872504779948,TENTATIVE=154.749 +TIME=1167872504782637,TENTATIVE=153.718 +TIME=1167872504785329,TENTATIVE=152.709 +TIME=1167872504787926,TENTATIVE=151.843 +TIME=1167872504790614,TENTATIVE=150.85 +TIME=1167872504793309,TENTATIVE=149.853 +TIME=1167872504795905,TENTATIVE=149.03 +TIME=1167872504798594,TENTATIVE=148.079 +TIME=1167872504801288,TENTATIVE=147.132 +TIME=1167872504803883,TENTATIVE=146.32 +TIME=1167872504806573,TENTATIVE=145.408 +TIME=1167872504809266,TENTATIVE=144.495 +TIME=1167872504811868,TENTATIVE=143.711 +TIME=1167872504814549,TENTATIVE=142.829 +TIME=1167872504817245,TENTATIVE=141.955 +TIME=1167872504819855,TENTATIVE=141.209 +TIME=1167872504822531,TENTATIVE=140.368 +TIME=1167872504825223,TENTATIVE=139.509 +TIME=1167872504827821,TENTATIVE=138.795 +TIME=1167872504830509,TENTATIVE=137.97 +TIME=1167872504833200,TENTATIVE=137.174 +TIME=1167872504835796,TENTATIVE=136.449 +TIME=1167872504838486,TENTATIVE=135.642 +TIME=1167872504841179,TENTATIVE=134.856 +TIME=1167872504843776,TENTATIVE=134.18 +TIME=1167872504846465,TENTATIVE=133.406 +TIME=1167872504849159,TENTATIVE=132.632 +TIME=1167872504851755,TENTATIVE=131.987 +TIME=1167872504854447,TENTATIVE=131.234 +TIME=1167872504857138,TENTATIVE=130.492 +TIME=1167872504859734,TENTATIVE=129.855 +TIME=1167872504862428,TENTATIVE=129.132 +TIME=1167872504865117,TENTATIVE=128.418 +TIME=1167872504867710,TENTATIVE=127.809 +TIME=1167872504870401,TENTATIVE=127.098 +TIME=1167872504873093,TENTATIVE=126.408 +TIME=1167872504875689,TENTATIVE=125.818 +TIME=1167872504878380,TENTATIVE=125.136 +TIME=1167872504881071,TENTATIVE=124.453 +TIME=1167872504883668,TENTATIVE=123.885 +TIME=1167872504886357,TENTATIVE=123.227 +TIME=1167872504889051,TENTATIVE=122.566 +TIME=1167872504891646,TENTATIVE=122.006 +TIME=1167872504894343,TENTATIVE=121.364 +TIME=1167872504897031,TENTATIVE=120.733 +TIME=1167872504899622,TENTATIVE=120.196 +TIME=1167872504902332,TENTATIVE=119.549 +TIME=1167872504905008,TENTATIVE=118.955 +TIME=1167872504907604,TENTATIVE=118.428 +TIME=1167872504910295,TENTATIVE=117.822 +TIME=1167872504912987,TENTATIVE=117.22 +TIME=1167872504915583,TENTATIVE=116.717 +TIME=1167872504918272,TENTATIVE=116.131 +TIME=1167872504920965,TENTATIVE=115.546 +TIME=1167872504923560,TENTATIVE=115.048 +TIME=1167872504926250,TENTATIVE=114.486 +TIME=1167872504928945,TENTATIVE=113.919 +TIME=1167872504931539,TENTATIVE=113.438 +TIME=1167872504934229,TENTATIVE=112.879 +TIME=1167872504936925,AUTHORITATIVE=112.333 +TIME=1167872504939517,TENTATIVE=113.515 +TIME=1167872504942206,TENTATIVE=112.941 +TIME=1167872504944902,AUTHORITATIVE=112.383 +TIME=1167872504947497,TENTATIVE=113.548 +TIME=1167872504950185,TENTATIVE=112.993 +TIME=1167872504952879,AUTHORITATIVE=112.436 +TIME=1167872504955473,TENTATIVE=113.605 +TIME=1167872504958166,TENTATIVE=113.045 +TIME=1167872504960857,AUTHORITATIVE=112.491 +TIME=1167872504963453,TENTATIVE=113.656 +TIME=1167872504966143,TENTATIVE=113.101 +TIME=1167872504968837,AUTHORITATIVE=112.542 +TIME=1167872504971432,TENTATIVE=113.71 +TIME=1167872504974123,TENTATIVE=113.153 +TIME=1167872504976819,AUTHORITATIVE=112.591 +TIME=1167872504979410,TENTATIVE=113.765 +TIME=1167872504982101,TENTATIVE=113.205 +TIME=1167872504984805,AUTHORITATIVE=112.639 +TIME=1167872504987387,TENTATIVE=113.821 +TIME=1167872504990079,TENTATIVE=113.261 +TIME=1167872504992770,AUTHORITATIVE=112.702 +TIME=1167872504995368,TENTATIVE=113.872 +TIME=1167872504998057,TENTATIVE=113.315 +TIME=1167872505000750,TENTATIVE=112.753 +TIME=1167872505003349,AUTHORITATIVE=112.283 +TIME=1167872505006036,TENTATIVE=113.367 +TIME=1167872505008728,TENTATIVE=112.806 +TIME=1167872505011329,AUTHORITATIVE=112.334 +TIME=1167872505014015,TENTATIVE=113.446 +TIME=1167872505016709,TENTATIVE=112.886 +TIME=1167872505019304,AUTHORITATIVE=112.407 +TIME=1167872505021993,TENTATIVE=113.498 +TIME=1167872505024685,TENTATIVE=112.943 +TIME=1167872505027280,AUTHORITATIVE=112.465 +TIME=1167872505029972,TENTATIVE=113.554 +TIME=1167872505032664,TENTATIVE=112.995 +TIME=1167872505035259,AUTHORITATIVE=112.516 +TIME=1167872505037950,TENTATIVE=113.607 +TIME=1167872505040642,TENTATIVE=113.048 +TIME=1167872505043238,AUTHORITATIVE=112.568 +TIME=1167872505045929,TENTATIVE=113.658 +TIME=1167872505048622,TENTATIVE=113.101 +TIME=1167872505051229,AUTHORITATIVE=112.612 +TIME=1167872505053909,TENTATIVE=113.712 +TIME=1167872505056600,TENTATIVE=113.154 +TIME=1167872505059204,AUTHORITATIVE=112.668 +TIME=1167872505061886,TENTATIVE=113.768 +TIME=1167872505064579,TENTATIVE=113.208 +TIME=1167872505067175,AUTHORITATIVE=112.728 +TIME=1167872505069865,TENTATIVE=113.824 +TIME=1167872505072559,TENTATIVE=113.264 +TIME=1167872505075153,AUTHORITATIVE=112.783 +TIME=1167872505077842,TENTATIVE=113.879 +TIME=1167872505080537,TENTATIVE=113.316 +TIME=1167872505083130,TENTATIVE=112.837 +TIME=1167872505085826,AUTHORITATIVE=112.289 +TIME=1167872505088515,TENTATIVE=113.37 +TIME=1167872505091111,TENTATIVE=112.891 +TIME=1167872505093806,AUTHORITATIVE=112.342 +TIME=1167872505096493,TENTATIVE=113.436 +TIME=1167872505099090,TENTATIVE=112.957 +TIME=1167872505101781,AUTHORITATIVE=112.402 +TIME=1167872505104471,TENTATIVE=113.492 +TIME=1167872505107072,TENTATIVE=113.008 +TIME=1167872505109759,AUTHORITATIVE=112.455 +TIME=1167872505112449,TENTATIVE=113.546 +TIME=1167872505115046,TENTATIVE=113.065 +TIME=1167872505117735,AUTHORITATIVE=112.51 +TIME=1167872505120428,TENTATIVE=113.599 +TIME=1167872505123024,TENTATIVE=113.119 +TIME=1167872505125714,AUTHORITATIVE=112.562 +TIME=1167872505128406,TENTATIVE=113.65 +TIME=1167872505131003,TENTATIVE=113.167 +TIME=1167872505133703,AUTHORITATIVE=112.605 +TIME=1167872505136385,TENTATIVE=113.706 +TIME=1167872505138981,TENTATIVE=113.226 +TIME=1167872505141685,AUTHORITATIVE=112.657 +TIME=1167872505144364,TENTATIVE=113.76 +TIME=1167872505146960,TENTATIVE=113.28 +TIME=1167872505149651,AUTHORITATIVE=112.722 +TIME=1167872505152344,TENTATIVE=113.813 +TIME=1167872505154938,TENTATIVE=113.331 +TIME=1167872505157628,AUTHORITATIVE=112.775 +TIME=1167872505160320,TENTATIVE=113.871 +TIME=1167872505162917,TENTATIVE=113.388 +TIME=1167872505165607,TENTATIVE=112.83 +TIME=1167872505168300,AUTHORITATIVE=112.285 +TIME=1167872505170896,TENTATIVE=113.442 +TIME=1167872505173584,TENTATIVE=112.886 +TIME=1167872505176284,AUTHORITATIVE=112.333 +TIME=1167872505178874,TENTATIVE=113.513 +TIME=1167872505181563,TENTATIVE=112.957 +TIME=1167872505184256,AUTHORITATIVE=112.412 +TIME=1167872505186852,TENTATIVE=113.574 +TIME=1167872505189546,TENTATIVE=113.013 +TIME=1167872505192235,AUTHORITATIVE=112.46 +TIME=1167872505194832,TENTATIVE=113.626 +TIME=1167872505197520,TENTATIVE=113.073 +TIME=1167872505200213,AUTHORITATIVE=112.513 +TIME=1167872505202809,TENTATIVE=113.682 +TIME=1167872505205501,TENTATIVE=113.123 +TIME=1167872505208190,AUTHORITATIVE=112.568 +TIME=1167872505210789,TENTATIVE=113.735 +TIME=1167872505213477,TENTATIVE=113.179 +TIME=1167872505216185,AUTHORITATIVE=112.609 +TIME=1167872505218765,TENTATIVE=113.795 +TIME=1167872505221455,TENTATIVE=113.233 +TIME=1167872505224156,AUTHORITATIVE=112.668 +TIME=1167872505226745,TENTATIVE=113.846 +TIME=1167872505229434,TENTATIVE=113.288 +TIME=1167872505232129,AUTHORITATIVE=112.728 +TIME=1167872505234723,TENTATIVE=113.904 +TIME=1167872505237413,TENTATIVE=113.344 +TIME=1167872505240106,TENTATIVE=112.785 +TIME=1167872505242707,AUTHORITATIVE=112.315 +TIME=1167872505245392,TENTATIVE=113.4 +TIME=1167872505248085,TENTATIVE=112.84 +TIME=1167872505250683,AUTHORITATIVE=112.373 +TIME=1167872505253369,TENTATIVE=113.46 +TIME=1167872505256062,TENTATIVE=112.902 +TIME=1167872505258666,AUTHORITATIVE=112.418 +TIME=1167872505261349,TENTATIVE=113.513 +TIME=1167872505264041,TENTATIVE=112.959 +TIME=1167872505266637,AUTHORITATIVE=112.479 +TIME=1167872505269327,TENTATIVE=113.571 +TIME=1167872505272028,TENTATIVE=113.006 +TIME=1167872505274616,AUTHORITATIVE=112.534 +TIME=1167872505277307,TENTATIVE=113.626 +TIME=1167872505279999,TENTATIVE=113.07 +TIME=1167872505282594,AUTHORITATIVE=112.591 +TIME=1167872505285285,TENTATIVE=113.681 +TIME=1167872505287979,TENTATIVE=113.122 +TIME=1167872505290584,AUTHORITATIVE=112.634 +TIME=1167872505293263,TENTATIVE=113.739 +TIME=1167872505295957,TENTATIVE=113.177 +TIME=1167872505298553,AUTHORITATIVE=112.696 +TIME=1167872505301242,TENTATIVE=113.79 +TIME=1167872505303935,TENTATIVE=113.231 +TIME=1167872505306529,AUTHORITATIVE=112.751 +TIME=1167872505309219,TENTATIVE=113.846 +TIME=1167872505311914,TENTATIVE=113.284 +TIME=1167872505314508,AUTHORITATIVE=112.803 +TIME=1167872505317197,TENTATIVE=113.899 +TIME=1167872505319894,TENTATIVE=113.334 +TIME=1167872505322488,TENTATIVE=112.855 +TIME=1167872505325182,AUTHORITATIVE=112.309 +TIME=1167872505327871,TENTATIVE=113.39 +TIME=1167872505330468,TENTATIVE=112.907 +TIME=1167872505333157,AUTHORITATIVE=112.363 +TIME=1167872505335849,TENTATIVE=113.456 +TIME=1167872505338444,TENTATIVE=112.978 +TIME=1167872505341134,AUTHORITATIVE=112.425 +TIME=1167872505343827,TENTATIVE=113.511 +TIME=1167872505346423,TENTATIVE=113.032 +TIME=1167872505349114,AUTHORITATIVE=112.478 +TIME=1167872505351807,TENTATIVE=113.575 +TIME=1167872505354403,TENTATIVE=113.096 +TIME=1167872505357091,AUTHORITATIVE=112.541 +TIME=1167872505359785,TENTATIVE=113.628 +TIME=1167872505362380,TENTATIVE=113.148 +TIME=1167872505365069,AUTHORITATIVE=112.592 +TIME=1167872505367764,TENTATIVE=113.679 +TIME=1167872505370358,TENTATIVE=113.202 +TIME=1167872505373060,AUTHORITATIVE=112.633 +TIME=1167872505375741,TENTATIVE=113.737 +TIME=1167872505378337,TENTATIVE=113.254 +TIME=1167872505381034,AUTHORITATIVE=112.691 +TIME=1167872505383720,TENTATIVE=113.788 +TIME=1167872505386315,TENTATIVE=113.308 +TIME=1167872505389005,AUTHORITATIVE=112.749 +TIME=1167872505391698,TENTATIVE=113.843 +TIME=1167872505394295,TENTATIVE=113.359 +TIME=1167872505396985,AUTHORITATIVE=112.8 +TIME=1167872505399677,TENTATIVE=113.894 +TIME=1167872505402274,TENTATIVE=113.408 +TIME=1167872505404964,TENTATIVE=112.852 +TIME=1167872505407661,AUTHORITATIVE=112.304 +TIME=1167872505410251,TENTATIVE=113.464 +TIME=1167872505412941,TENTATIVE=112.905 +TIME=1167872505415642,AUTHORITATIVE=112.352 +TIME=1167872505418229,TENTATIVE=113.538 +TIME=1167872505420919,TENTATIVE=112.982 +TIME=1167872505423614,AUTHORITATIVE=112.423 +TIME=1167872505426207,TENTATIVE=113.592 +TIME=1167872505428901,TENTATIVE=113.032 +TIME=1167872505431593,AUTHORITATIVE=112.476 +TIME=1167872505434187,TENTATIVE=113.646 +TIME=1167872505436876,TENTATIVE=113.089 +TIME=1167872505439567,AUTHORITATIVE=112.536 +TIME=1167872505442166,TENTATIVE=113.701 +TIME=1167872505444855,TENTATIVE=113.145 +TIME=1167872505447548,AUTHORITATIVE=112.586 +TIME=1167872505450145,TENTATIVE=113.753 +TIME=1167872505452834,TENTATIVE=113.198 +TIME=1167872505455537,AUTHORITATIVE=112.63 +TIME=1167872505458122,TENTATIVE=113.809 +TIME=1167872505460813,TENTATIVE=113.251 +TIME=1167872505463520,AUTHORITATIVE=112.678 +TIME=1167872505466100,TENTATIVE=113.862 +TIME=1167872505468793,TENTATIVE=113.302 +TIME=1167872505471484,TENTATIVE=112.743 +TIME=1167872505474081,AUTHORITATIVE=112.275 +TIME=1167872505476771,TENTATIVE=113.354 +TIME=1167872505479461,TENTATIVE=112.798 +TIME=1167872505482065,AUTHORITATIVE=112.323 +TIME=1167872505484747,TENTATIVE=113.429 +TIME=1167872505487441,TENTATIVE=112.853 +TIME=1167872505490038,AUTHORITATIVE=112.375 +TIME=1167872505492727,TENTATIVE=113.465 +TIME=1167872505495419,TENTATIVE=112.908 +TIME=1167872505498017,AUTHORITATIVE=112.428 +TIME=1167872505500705,TENTATIVE=113.521 +TIME=1167872505503399,TENTATIVE=112.962 +TIME=1167872505505992,AUTHORITATIVE=112.484 +TIME=1167872505508683,TENTATIVE=113.574 +TIME=1167872505511384,TENTATIVE=113.008 +TIME=1167872505513973,AUTHORITATIVE=112.534 +TIME=1167872505516663,TENTATIVE=113.628 +TIME=1167872505519355,TENTATIVE=113.068 +TIME=1167872505521950,AUTHORITATIVE=112.589 +TIME=1167872505524641,TENTATIVE=113.689 +TIME=1167872505527335,TENTATIVE=113.128 +TIME=1167872505529942,AUTHORITATIVE=112.639 +TIME=1167872505532618,TENTATIVE=113.743 +TIME=1167872505535312,TENTATIVE=113.182 +TIME=1167872505537910,AUTHORITATIVE=112.701 +TIME=1167872505540610,TENTATIVE=113.786 +TIME=1167872505543292,TENTATIVE=113.234 +TIME=1167872505545886,AUTHORITATIVE=112.756 +TIME=1167872505548578,TENTATIVE=113.847 +TIME=1167872505551269,TENTATIVE=113.292 +TIME=1167872505553866,AUTHORITATIVE=112.808 +TIME=1167872505556554,TENTATIVE=113.905 +TIME=1167872505559247,TENTATIVE=113.341 +TIME=1167872505561842,TENTATIVE=112.86 +TIME=1167872505564537,AUTHORITATIVE=112.312 +TIME=1167872505567225,TENTATIVE=113.392 +TIME=1167872505569824,TENTATIVE=112.908 +TIME=1167872505572513,AUTHORITATIVE=112.365 +TIME=1167872505575206,TENTATIVE=113.456 +TIME=1167872505577799,TENTATIVE=112.978 +TIME=1167872505580492,AUTHORITATIVE=112.423 +TIME=1167872505583184,TENTATIVE=113.51 +TIME=1167872505585779,TENTATIVE=113.03 +TIME=1167872505588468,AUTHORITATIVE=112.478 +TIME=1167872505591161,TENTATIVE=113.566 +TIME=1167872505593758,TENTATIVE=113.088 +TIME=1167872505596445,AUTHORITATIVE=112.534 +TIME=1167872505599140,TENTATIVE=113.622 +TIME=1167872505601736,TENTATIVE=113.141 +TIME=1167872505604437,AUTHORITATIVE=112.575 +TIME=1167872505607119,TENTATIVE=113.673 +TIME=1167872505609716,TENTATIVE=113.192 +TIME=1167872505612411,AUTHORITATIVE=112.631 +TIME=1167872505615098,TENTATIVE=113.725 +TIME=1167872505617693,TENTATIVE=113.246 +TIME=1167872505620384,AUTHORITATIVE=112.689 +TIME=1167872505623076,TENTATIVE=113.783 +TIME=1167872505625674,TENTATIVE=113.3 +TIME=1167872505628361,AUTHORITATIVE=112.745 +TIME=1167872505631055,TENTATIVE=113.838 +TIME=1167872505633650,TENTATIVE=113.357 +TIME=1167872505636339,AUTHORITATIVE=112.8 +TIME=1167872505639036,TENTATIVE=113.89 +TIME=1167872505641630,TENTATIVE=113.408 +TIME=1167872505644319,TENTATIVE=112.85 +TIME=1167872505647018,AUTHORITATIVE=112.301 +TIME=1167872505649607,TENTATIVE=113.465 +TIME=1167872505652297,TENTATIVE=112.905 +TIME=1167872505654991,AUTHORITATIVE=112.359 +TIME=1167872505657590,TENTATIVE=113.531 +TIME=1167872505660279,TENTATIVE=112.977 +TIME=1167872505663074,AUTHORITATIVE=112.339 +TIME=1167872505665564,TENTATIVE=113.592 +TIME=1167872505668254,TENTATIVE=113.034 +TIME=1167872505670947,AUTHORITATIVE=112.476 +TIME=1167872505673543,TENTATIVE=113.645 +TIME=1167872505676232,TENTATIVE=113.089 +TIME=1167872505678926,AUTHORITATIVE=112.531 +TIME=1167872505681521,TENTATIVE=113.699 +TIME=1167872505684213,TENTATIVE=113.138 +TIME=1167872505686915,AUTHORITATIVE=112.575 +TIME=1167872505689501,TENTATIVE=113.753 +TIME=1167872505692190,TENTATIVE=113.205 +TIME=1167872505694902,AUTHORITATIVE=112.63 +TIME=1167872505697479,TENTATIVE=113.816 +TIME=1167872505700168,TENTATIVE=113.261 +TIME=1167872505702864,AUTHORITATIVE=112.699 +TIME=1167872505705456,TENTATIVE=113.874 +TIME=1167872505708147,TENTATIVE=113.315 +TIME=1167872505710839,TENTATIVE=112.758 +TIME=1167872505713440,AUTHORITATIVE=112.285 +TIME=1167872505716125,TENTATIVE=113.369 +TIME=1167872505718818,TENTATIVE=112.809 +TIME=1167872505721414,AUTHORITATIVE=112.344 +TIME=1167872505724105,TENTATIVE=113.462 +TIME=1167872505726797,TENTATIVE=112.904 +TIME=1167872505729394,AUTHORITATIVE=112.426 +TIME=1167872505732082,TENTATIVE=113.516 +TIME=1167872505734776,TENTATIVE=112.956 +TIME=1167872505737371,AUTHORITATIVE=112.479 +TIME=1167872505740061,TENTATIVE=113.571 +TIME=1167872505742756,TENTATIVE=113.013 +TIME=1167872505745349,AUTHORITATIVE=112.534 +TIME=1167872505748038,TENTATIVE=113.626 +TIME=1167872505750733,TENTATIVE=113.066 +TIME=1167872505753333,AUTHORITATIVE=112.583 +TIME=1167872505756018,TENTATIVE=113.681 +TIME=1167872505758711,TENTATIVE=113.12 +TIME=1167872505761320,AUTHORITATIVE=112.633 +TIME=1167872505763998,TENTATIVE=113.735 +TIME=1167872505766692,TENTATIVE=113.174 +TIME=1167872505769287,AUTHORITATIVE=112.694 +TIME=1167872505771973,TENTATIVE=113.793 +TIME=1167872505774668,TENTATIVE=113.23 +TIME=1167872505777262,AUTHORITATIVE=112.751 +TIME=1167872505779955,TENTATIVE=113.843 +TIME=1167872505782647,TENTATIVE=113.28 +TIME=1167872505785242,AUTHORITATIVE=112.801 +TIME=1167872505787932,TENTATIVE=113.897 +TIME=1167872505790625,TENTATIVE=113.338 +TIME=1167872505793219,TENTATIVE=112.856 +TIME=1167872505795919,AUTHORITATIVE=112.305 +TIME=1167872505798602,TENTATIVE=113.392 +TIME=1167872505801200,TENTATIVE=112.908 +TIME=1167872505803890,AUTHORITATIVE=112.362 +TIME=1167872505806583,TENTATIVE=113.456 +TIME=1167872505809178,TENTATIVE=112.977 +TIME=1167872505811869,AUTHORITATIVE=112.421 +TIME=1167872505814564,TENTATIVE=113.506 +TIME=1167872505817156,TENTATIVE=113.03 +TIME=1167872505819847,AUTHORITATIVE=112.476 +TIME=1167872505822539,TENTATIVE=113.564 +TIME=1167872505825136,TENTATIVE=113.081 +TIME=1167872505827825,AUTHORITATIVE=112.528 +TIME=1167872505830517,TENTATIVE=113.617 +TIME=1167872505833114,TENTATIVE=113.135 +TIME=1167872505835820,AUTHORITATIVE=112.567 +TIME=1167872505838496,TENTATIVE=113.673 +TIME=1167872505841092,TENTATIVE=113.194 +TIME=1167872505843791,AUTHORITATIVE=112.628 +TIME=1167872505846476,TENTATIVE=113.727 +TIME=1167872505849071,TENTATIVE=113.246 +TIME=1167872505851762,AUTHORITATIVE=112.689 +TIME=1167872505854453,TENTATIVE=113.793 +TIME=1167872505857051,TENTATIVE=113.311 +TIME=1167872505859739,AUTHORITATIVE=112.754 +TIME=1167872505862433,TENTATIVE=113.846 +TIME=1167872505865027,TENTATIVE=113.367 +TIME=1167872505867718,AUTHORITATIVE=112.806 +TIME=1167872505870414,TENTATIVE=113.897 +TIME=1167872505873006,TENTATIVE=113.416 +TIME=1167872505875698,TENTATIVE=112.856 +TIME=1167872505878394,AUTHORITATIVE=112.309 +TIME=1167872505880986,TENTATIVE=113.47 +TIME=1167872505883676,TENTATIVE=112.912 +TIME=1167872505886368,AUTHORITATIVE=112.365 +TIME=1167872505888965,TENTATIVE=113.539 +TIME=1167872505891653,TENTATIVE=112.985 +TIME=1167872505894346,AUTHORITATIVE=112.429 +TIME=1167872505896941,TENTATIVE=113.597 +TIME=1167872505899632,TENTATIVE=113.039 +TIME=1167872505902324,AUTHORITATIVE=112.483 +TIME=1167872505904920,TENTATIVE=113.653 +TIME=1167872505907612,TENTATIVE=113.096 +TIME=1167872505910303,AUTHORITATIVE=112.541 +TIME=1167872505912899,TENTATIVE=113.707 +TIME=1167872505915588,TENTATIVE=113.151 +TIME=1167872505918293,AUTHORITATIVE=112.581 +TIME=1167872505920877,TENTATIVE=113.762 +TIME=1167872505923568,TENTATIVE=113.203 +TIME=1167872505926278,AUTHORITATIVE=112.631 +TIME=1167872505928858,TENTATIVE=113.816 +TIME=1167872505931547,TENTATIVE=113.257 +TIME=1167872505934239,AUTHORITATIVE=112.701 +TIME=1167872505936834,TENTATIVE=113.874 +TIME=1167872505939523,TENTATIVE=113.318 +TIME=1167872505942218,TENTATIVE=112.754 +TIME=1167872505944820,AUTHORITATIVE=112.283 +TIME=1167872505947504,TENTATIVE=113.367 +TIME=1167872505950195,TENTATIVE=112.809 +TIME=1167872505952792,AUTHORITATIVE=112.341 +TIME=1167872505955483,TENTATIVE=113.459 +TIME=1167872505958174,TENTATIVE=112.905 +TIME=1167872505960770,AUTHORITATIVE=112.426 +TIME=1167872505963459,TENTATIVE=113.518 +TIME=1167872505966153,TENTATIVE=112.959 +TIME=1167872505968749,AUTHORITATIVE=112.481 +TIME=1167872505971440,TENTATIVE=113.569 +TIME=1167872505974135,TENTATIVE=113.009 +TIME=1167872505976729,AUTHORITATIVE=112.533 +TIME=1167872505979418,TENTATIVE=113.625 +TIME=1167872505982110,TENTATIVE=113.068 +TIME=1167872505984710,AUTHORITATIVE=112.588 +TIME=1167872505987395,TENTATIVE=113.684 +TIME=1167872505990090,TENTATIVE=113.122 +TIME=1167872505992700,AUTHORITATIVE=112.631 +TIME=1167872505995373,TENTATIVE=113.735 +TIME=1167872505998067,TENTATIVE=113.174 +TIME=1167872506000665,AUTHORITATIVE=112.693 +TIME=1167872506003352,TENTATIVE=113.79 +TIME=1167872506006047,TENTATIVE=113.228 +TIME=1167872506008642,AUTHORITATIVE=112.748 +TIME=1167872506011331,TENTATIVE=113.844 +TIME=1167872506014026,TENTATIVE=113.292 +TIME=1167872506016620,AUTHORITATIVE=112.809 +TIME=1167872506019310,TENTATIVE=113.904 +TIME=1167872506022004,TENTATIVE=113.341 +TIME=1167872506024599,TENTATIVE=112.86 +TIME=1167872506027292,AUTHORITATIVE=112.315 +TIME=1167872506029981,TENTATIVE=113.397 +TIME=1167872506032578,TENTATIVE=112.912 +TIME=1167872506035271,AUTHORITATIVE=112.367 +TIME=1167872506037961,TENTATIVE=113.456 +TIME=1167872506040556,TENTATIVE=112.977 +TIME=1167872506043247,AUTHORITATIVE=112.421 +TIME=1167872506045939,TENTATIVE=113.51 +TIME=1167872506048536,TENTATIVE=113.029 +TIME=1167872506051223,AUTHORITATIVE=112.478 +TIME=1167872506053918,TENTATIVE=113.561 +TIME=1167872506056521,TENTATIVE=113.078 +TIME=1167872506059202,AUTHORITATIVE=112.528 +TIME=1167872506061896,TENTATIVE=113.618 +TIME=1167872506064492,TENTATIVE=113.138 +TIME=1167872506067193,AUTHORITATIVE=112.573 +TIME=1167872506069875,TENTATIVE=113.671 +TIME=1167872506072472,TENTATIVE=113.19 +TIME=1167872506075169,AUTHORITATIVE=112.628 +TIME=1167872506077856,TENTATIVE=113.725 +TIME=1167872506080449,TENTATIVE=113.248 +TIME=1167872506083139,AUTHORITATIVE=112.691 +TIME=1167872506085830,TENTATIVE=113.786 +TIME=1167872506088427,TENTATIVE=113.303 +TIME=1167872506091116,AUTHORITATIVE=112.748 +TIME=1167872506093810,TENTATIVE=113.841 +TIME=1167872506096405,TENTATIVE=113.36 +TIME=1167872506099097,AUTHORITATIVE=112.801 +TIME=1167872506101791,TENTATIVE=113.894 +TIME=1167872506104383,TENTATIVE=113.416 +TIME=1167872506107076,TENTATIVE=112.853 +TIME=1167872506109773,AUTHORITATIVE=112.305 +TIME=1167872506112362,TENTATIVE=113.469 +TIME=1167872506115054,TENTATIVE=112.91 +TIME=1167872506117745,AUTHORITATIVE=112.367 +TIME=1167872506120340,TENTATIVE=113.539 +TIME=1167872506123036,TENTATIVE=112.98 +TIME=1167872506125724,AUTHORITATIVE=112.434 +TIME=1167872506128319,TENTATIVE=113.595 +TIME=1167872506131010,TENTATIVE=113.039 +TIME=1167872506133703,AUTHORITATIVE=112.479 +TIME=1167872506136298,TENTATIVE=113.65 +TIME=1167872506138988,TENTATIVE=113.094 +TIME=1167872506141681,AUTHORITATIVE=112.534 +TIME=1167872506144277,TENTATIVE=113.702 +TIME=1167872506146966,TENTATIVE=113.146 +TIME=1167872506149673,AUTHORITATIVE=112.575 +TIME=1167872506152256,TENTATIVE=113.755 +TIME=1167872506154946,TENTATIVE=113.195 +TIME=1167872506157642,AUTHORITATIVE=112.633 +TIME=1167872506160233,TENTATIVE=113.808 +TIME=1167872506162924,TENTATIVE=113.249 +TIME=1167872506165617,AUTHORITATIVE=112.689 +TIME=1167872506168211,TENTATIVE=113.861 +TIME=1167872506170902,TENTATIVE=113.3 +TIME=1167872506173596,AUTHORITATIVE=112.74 +TIME=1167872506176194,TENTATIVE=113.91 +TIME=1167872506178882,TENTATIVE=113.354 +TIME=1167872506181573,TENTATIVE=112.796 +TIME=1167872506184171,AUTHORITATIVE=112.336 +TIME=1167872506186861,TENTATIVE=113.459 +TIME=1167872506189552,TENTATIVE=112.9 +TIME=1167872506192148,AUTHORITATIVE=112.423 +TIME=1167872506194839,TENTATIVE=113.515 +TIME=1167872506197529,TENTATIVE=112.96 +TIME=1167872506200126,AUTHORITATIVE=112.479 +TIME=1167872506202814,TENTATIVE=113.572 +TIME=1167872506205510,TENTATIVE=113.013 +TIME=1167872506208106,AUTHORITATIVE=112.533 +TIME=1167872506210796,TENTATIVE=113.625 +TIME=1167872506213492,TENTATIVE=113.065 +TIME=1167872506216090,AUTHORITATIVE=112.583 +TIME=1167872506218774,TENTATIVE=113.678 +TIME=1167872506221468,TENTATIVE=113.119 +TIME=1167872506224079,AUTHORITATIVE=112.625 +TIME=1167872506226750,TENTATIVE=113.735 +TIME=1167872506229446,TENTATIVE=113.172 +TIME=1167872506232043,AUTHORITATIVE=112.693 +TIME=1167872506234730,TENTATIVE=113.791 +TIME=1167872506237423,TENTATIVE=113.23 +TIME=1167872506240018,AUTHORITATIVE=112.749 +TIME=1167872506242708,TENTATIVE=113.846 +TIME=1167872506245402,TENTATIVE=113.287 +TIME=1167872506247996,AUTHORITATIVE=112.806 +TIME=1167872506250688,TENTATIVE=113.9 +TIME=1167872506253381,TENTATIVE=113.339 +TIME=1167872506255976,TENTATIVE=112.86 +TIME=1167872506258673,AUTHORITATIVE=112.31 +TIME=1167872506261359,TENTATIVE=113.392 +TIME=1167872506263955,TENTATIVE=112.912 +TIME=1167872506266645,AUTHORITATIVE=112.367 +TIME=1167872506269337,TENTATIVE=113.459 +TIME=1167872506271932,TENTATIVE=112.982 +TIME=1167872506274624,AUTHORITATIVE=112.425 +TIME=1167872506277315,TENTATIVE=113.511 +TIME=1167872506279912,TENTATIVE=113.032 +TIME=1167872506282602,AUTHORITATIVE=112.478 +TIME=1167872506285294,TENTATIVE=113.567 +TIME=1167872506287892,TENTATIVE=113.088 +TIME=1167872506290581,AUTHORITATIVE=112.534 +TIME=1167872506293275,TENTATIVE=113.622 +TIME=1167872506295870,TENTATIVE=113.143 +TIME=1167872506298570,AUTHORITATIVE=112.578 +TIME=1167872506301253,TENTATIVE=113.676 +TIME=1167872506303848,TENTATIVE=113.198 +TIME=1167872506306546,AUTHORITATIVE=112.633 +TIME=1167872506309230,TENTATIVE=113.734 +TIME=1167872506311826,TENTATIVE=113.252 +TIME=1167872506314517,AUTHORITATIVE=112.696 +TIME=1167872506317208,TENTATIVE=113.79 +TIME=1167872506319805,TENTATIVE=113.308 +TIME=1167872506322494,AUTHORITATIVE=112.751 +TIME=1167872506325187,TENTATIVE=113.843 +TIME=1167872506327783,TENTATIVE=113.362 +TIME=1167872506330475,AUTHORITATIVE=112.801 +TIME=1167872506333169,TENTATIVE=113.895 +TIME=1167872506335761,TENTATIVE=113.416 +TIME=1167872506338465,TENTATIVE=112.847 +TIME=1167872506341151,AUTHORITATIVE=112.305 +TIME=1167872506343740,TENTATIVE=113.493 +TIME=1167872506346429,TENTATIVE=112.918 +TIME=1167872506349123,AUTHORITATIVE=112.371 +TIME=1167872506351719,TENTATIVE=113.541 +TIME=1167872506354409,TENTATIVE=112.987 +TIME=1167872506357102,AUTHORITATIVE=112.428 +TIME=1167872506359699,TENTATIVE=113.595 +TIME=1167872506362386,TENTATIVE=113.042 +TIME=1167872506365080,AUTHORITATIVE=112.483 +TIME=1167872506367676,TENTATIVE=113.653 +TIME=1167872506370365,TENTATIVE=113.096 +TIME=1167872506373059,AUTHORITATIVE=112.537 +TIME=1167872506375656,TENTATIVE=113.709 +TIME=1167872506378343,TENTATIVE=113.153 +TIME=1167872506381048,AUTHORITATIVE=112.586 +TIME=1167872506383633,TENTATIVE=113.763 +TIME=1167872506386323,TENTATIVE=113.205 +TIME=1167872506389023,AUTHORITATIVE=112.643 +TIME=1167872506391612,TENTATIVE=113.818 +TIME=1167872506394303,TENTATIVE=113.257 +TIME=1167872506396994,AUTHORITATIVE=112.701 +TIME=1167872506399590,TENTATIVE=113.874 +TIME=1167872506402282,TENTATIVE=113.313 +TIME=1167872506404974,TENTATIVE=112.754 +TIME=1167872506407576,AUTHORITATIVE=112.283 +TIME=1167872506410258,TENTATIVE=113.369 +TIME=1167872506412952,TENTATIVE=112.809 +TIME=1167872506415547,AUTHORITATIVE=112.342 +TIME=1167872506418236,TENTATIVE=113.465 +TIME=1167872506420929,TENTATIVE=112.907 +TIME=1167872506423526,AUTHORITATIVE=112.428 +TIME=1167872506426216,TENTATIVE=113.516 +TIME=1167872506428907,TENTATIVE=112.959 +TIME=1167872506431505,AUTHORITATIVE=112.479 +TIME=1167872506434193,TENTATIVE=113.572 +TIME=1167872506436887,TENTATIVE=113.016 +TIME=1167872506439481,AUTHORITATIVE=112.537 +TIME=1167872506442173,TENTATIVE=113.628 +TIME=1167872506444866,TENTATIVE=113.07 +TIME=1167872506447462,AUTHORITATIVE=112.591 +TIME=1167872506450151,TENTATIVE=113.684 +TIME=1167872506452846,TENTATIVE=113.122 +TIME=1167872506455449,AUTHORITATIVE=112.638 +TIME=1167872506458129,TENTATIVE=113.739 +TIME=1167872506460822,TENTATIVE=113.181 +TIME=1167872506463417,AUTHORITATIVE=112.701 +TIME=1167872506466108,TENTATIVE=113.793 +TIME=1167872506468800,TENTATIVE=113.231 +TIME=1167872506471396,AUTHORITATIVE=112.751 +TIME=1167872506474088,TENTATIVE=113.846 +TIME=1167872506476779,TENTATIVE=113.287 +TIME=1167872506479374,AUTHORITATIVE=112.808 +TIME=1167872506482067,TENTATIVE=113.902 +TIME=1167872506484758,TENTATIVE=113.346 +TIME=1167872506487354,TENTATIVE=112.861 +TIME=1167872506490042,AUTHORITATIVE=112.32 +TIME=1167872506492736,TENTATIVE=113.398 +TIME=1167872506495332,TENTATIVE=112.918 +TIME=1167872506498021,AUTHORITATIVE=112.376 +TIME=1167872506500716,TENTATIVE=113.454 +TIME=1167872506503311,TENTATIVE=112.988 +TIME=1167872506506000,AUTHORITATIVE=112.433 +TIME=1167872506508696,TENTATIVE=113.518 +TIME=1167872506511289,TENTATIVE=113.042 +TIME=1167872506513979,AUTHORITATIVE=112.487 +TIME=1167872506516673,TENTATIVE=113.579 +TIME=1167872506519268,TENTATIVE=113.099 +TIME=1167872506521958,AUTHORITATIVE=112.542 +TIME=1167872506524652,TENTATIVE=113.631 +TIME=1167872506527248,TENTATIVE=113.151 +TIME=1167872506529936,AUTHORITATIVE=112.596 +TIME=1167872506532629,TENTATIVE=113.687 +TIME=1167872506535225,TENTATIVE=113.207 +TIME=1167872506537915,AUTHORITATIVE=112.652 +TIME=1167872506540606,TENTATIVE=113.745 diff --git a/pelab/magent/UDP/UdpClientDir/UdpClient.cc b/pelab/magent/UDP/UdpClientDir/UdpClient.cc new file mode 100644 index 0000000000000000000000000000000000000000..9a49cfcfd5f6a2bb7e3ab7a59946747351aeb742 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpClient.cc @@ -0,0 +1,468 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <sys/time.h> +#include <sys/select.h> +#include <pcap.h> +#include <errno.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <netinet/if_ether.h> +#include <net/ethernet.h> +#include <netinet/ether.h> +#include <unistd.h> +#include <fcntl.h> + +#define REMOTE_SERVER_PORT 1500 +#define MAX_MSG 1600 +#define SNAPLEN 96 + +#include "UdpThroughputSensor.h" +#include "UdpMinDelaySensor.h" +#include "UdpMaxDelaySensor.h" +#include "UdpPacketSensor.h" +#include "UdpState.h" + +pcap_t *pcapDescriptor = NULL; +UdpThroughputSensor *throughputSensor; +UdpMaxDelaySensor *maxDelaySensor; +UdpMinDelaySensor *minDelaySensor; +UdpPacketSensor *packetSensor; +char localIP[16] = ""; + +struct UdpState globalUdpState; + +unsigned long long getTimeMicro() +{ + struct timeval tp; + gettimeofday(&tp, NULL); + + unsigned long long tmpSecVal = tp.tv_sec; + unsigned long long tmpUsecVal = tp.tv_usec; + + return (tmpSecVal*1000*1000 + tmpUsecVal); +} + +// This is not being used - because we are using libpcap. +// This is useful if SO_TIMESTAMP option is used instead of the timestamps given by libpcap. +void handleUDPMsg(struct sockaddr_in *clientAddr, char *udpMessage, int messageLen, struct timeval *timeStampVal) +{ + /* + printf("Destination IP address = %s\n", inet_ntoa(ipPacket->ip_dst)); + printf("Source port = %d\n", ntohs(udpHdr->source)); + printf("Dest port = %d\n\n", ntohs(udpHdr->dest)); + */ + + //printf("Data being received = %c, %u, %lld, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1), *(unsigned long long*)(dataPtr + 5), udpLen); + + + unsigned char packetType = udpMessage[0]; + unsigned long long timeStamp = 0; + unsigned long long tmpSecVal = timeStampVal->tv_sec; + unsigned long long tmpUsecVal = timeStampVal->tv_usec; + + timeStamp = (tmpSecVal*1000*1000 + tmpUsecVal); + + int overheadLen = 46; + + if(packetType == '0')// This is a udp data packet arriving here. Send an + // application level acknowledgement packet for it. + + // TODO:The packet can also be leaving from this host - our libpcap filter + // ignores those for now - as such, nothing needs to be done for such packets. + { + /* + if(strcmp( inet_ntoa(ipPacket->ip_dst),"10.1.2.2" ) != 0 ) + { + packetSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp); + } + */ + } + else if(packetType == '1') + { + // We received an ACK, pass it on to the sensors. + // TODO: Ignore the ACKs being sent out from this host. + + // TODO: For now, we are just passing the packet data part. + // For this to work correctly when integrated with magent, + // we also need to pass the local port, remote port and + // remote IP address, so that the connection can be looked up. + + //Pass the received packet to udp sensors: + packetSensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp); + minDelaySensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp); + maxDelaySensor->capturePacket(udpMessage, messageLen,overheadLen, timeStamp); + throughputSensor->capturePacket(udpMessage, messageLen, overheadLen, timeStamp); + } + else + { + printf("ERROR: Unknown UDP packet received from remote agent\n"); + return; + } +} + + +void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr, u_char *const udpPacketStart, struct ip const *ipPacket) +{ + + // Get a pointer to the data section of the UDP packet. + u_char *dataPtr = udpPacketStart + 8; + unsigned short udpLen = ntohs(udpHdr->len); + + //printf("Data being received = %c, %u, %lld, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1), *(unsigned long long*)(dataPtr + 5), udpLen); + + + // Indicates whether this is a data packet or an app-level ACK. + // This is the first byte in the data section of packets sent by the magent. + unsigned char packetType = *(unsigned char *)(dataPtr); + + unsigned long long timeStamp = 0; + unsigned long long tmpSecVal = pcap_info->ts.tv_sec; + unsigned long long tmpUsecVal = pcap_info->ts.tv_usec; + + // Calculate the timestamp in microseconds when this packet + // was captured by libpcap. + timeStamp = (tmpSecVal*1000*1000 + tmpUsecVal); + + // Account for the size of the IP header, 8 bytes of UDP header, + // 14 bytes of ethernet header and 4 bytes of ethernet CRC. + // TODO: There might also be some ethernet padding if the packet + // size is less than the min. ethernet packet size 64 bytes. + int overheadLen = ipPacket->ip_hl*4 + 8 + 14 + 4; + + if(packetType == '0')// This is a udp data packet being sent from here. + // Pass it to the packet sensor so that the send event, time + // of sending and packet size are recorded. + { + if(strcmp( inet_ntoa(ipPacket->ip_dst),localIP ) != 0 ) + { + packetSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp); + } + } + else if(packetType == '1') + { + // We received an app-level UDP ACK, pass it on to the sensors. + // Ignore the ACKs being sent out from this host. We do not + // need to record anything about them. + + // TODO: For now, we are just passing the packet data part. + // For this to work correctly when integrated with magent, + // we also need to pass the local port, remote port and + // remote IP address, so that the connection can be looked up. + + if(strcmp( inet_ntoa(ipPacket->ip_dst),localIP ) == 0 ) + { + // Pass the captured packet to the udp sensors. + packetSensor->capturePacket(reinterpret_cast<char *> (dataPtr), udpLen - 8, overheadLen, timeStamp); + minDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp); + maxDelaySensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp); + throughputSensor->capturePacket(reinterpret_cast<char *>(dataPtr), udpLen - 8, overheadLen, timeStamp); + } + } + else + { + printf("ERROR: Unknown UDP packet received from remote agent\n"); + return; + } +} + +int getLinkLayer(struct pcap_pkthdr const *pcap_info, const u_char *pkt_data) +{ + unsigned int caplen = pcap_info->caplen; + + if (caplen < sizeof(struct ether_header)) + { + printf("A captured packet was too short to contain " + "an ethernet header"); + return -1; + } + else + { + struct ether_header * etherPacket = (struct ether_header *) pkt_data; + return ntohs(etherPacket->ether_type); + } +} + +void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_char *pkt_data) +{ + int packetType = getLinkLayer(pcap_info, pkt_data); + + if(packetType != ETHERTYPE_IP) + { + printf("Unknown link layer type: %d\n", packetType); + return; + } + + struct ip const *ipPacket; + size_t bytesLeft = pcap_info->caplen - sizeof(struct ether_header); + + if(bytesLeft < sizeof(struct ip)) + { + printf("Captured packet was too short to contain an IP header.\n"); + return; + } + + ipPacket = (struct ip const *)(pkt_data + sizeof(struct ether_header)); + int ipHeaderLength = ipPacket->ip_hl; + int ipVersion = ipPacket->ip_v; + + + if(ipVersion != 4) + { + printf("Captured IP packet is not IPV4.\n"); + return; + } + + if(ipHeaderLength < 5) + { + printf("Captured IP packet has header less than the minimum 20 bytes.\n"); + return; + } + + if(ipPacket->ip_p != IPPROTO_UDP) + { + printf("Captured packet is not a UDP packet.\n"); + return; + } + + // Ignore the IP options for now - but count their length. + ///////////////////////////////////////////////////////// + u_char *udpPacketStart = (u_char *)(pkt_data + sizeof(struct ether_header) + ipHeaderLength*4); + + struct udphdr const *udpPacket; + + udpPacket = (struct udphdr const *)(udpPacketStart); + + bytesLeft -= ipHeaderLength*4; + + if(bytesLeft < sizeof(struct udphdr)) + { + printf("Captured packet is too small to contain a UDP header.\n"); + return; + } + + handleUDP(pcap_info,udpPacket,udpPacketStart, ipPacket); +} + +void init_pcap(char *interface, unsigned int portNumber) +{ + struct bpf_program bpfProg; + char errBuf[PCAP_ERRBUF_SIZE]; + char filter[32] = ""; + + sprintf(filter," udp and port %d ", portNumber); + // IP Address and sub net mask. + bpf_u_int32 maskp, netp; + struct in_addr localAddress; + + pcap_lookupnet(interface, &netp, &maskp, errBuf); + pcapDescriptor = pcap_open_live(interface,SNAPLEN, 0, 0, errBuf); + localAddress.s_addr = netp; + + if(pcapDescriptor == NULL) + { + printf("Error opening device %s with libpcap = %s\n", interface, errBuf); + exit(1); + } + + pcap_compile(pcapDescriptor, &bpfProg, filter, 1, netp); + pcap_setfilter(pcapDescriptor, &bpfProg); + + pcap_setnonblock(pcapDescriptor, 1, errBuf); + +} + +int main(int argc, char *argv[]) +{ + + int sd, rc, i, n, flags, error; + socklen_t echoLen; + struct sockaddr_in cliAddr, remoteServAddr, echoServAddr; + struct hostent *h; + char msg[MAX_MSG]; + fd_set readFdSet, writeFdSet; + int packetCount = 0; + + + /* check command line args */ + if(argc < 7) + { + printf("usage : %s <local-interface> <local-IP> <serverName> <packetCount> <packetSize> <SendRate-bps>\n", argv[0]); + exit(1); + } + strcpy(localIP, argv[2]); + + /* get server IP address (no check if input is IP address or DNS name */ + h = gethostbyname(argv[3]); + + if(h==NULL) + { + printf("%s: unknown host '%s' \n", argv[0], argv[3]); + exit(1); + } + + printf("%s: sending data to '%s' (IP : %s) \n", argv[0], h->h_name, + inet_ntoa(*(struct in_addr *)h->h_addr_list[0])); + + remoteServAddr.sin_family = h->h_addrtype; + memcpy((char *) &remoteServAddr.sin_addr.s_addr, + h->h_addr_list[0], h->h_length); + remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT); + + /* socket creation */ + sd = socket(AF_INET,SOCK_DGRAM,0); + + if(sd<0) + { + printf("%s: cannot open socket \n",argv[0]); + exit(1); + } + + /* bind any port */ + cliAddr.sin_family = AF_INET; + cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); + cliAddr.sin_port = htons(3200); + + rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr)); + + if(rc<0) + { + printf("%s: cannot bind port\n", argv[0]); + exit(1); + } + + flags = 0; + + // Initialize the libpcap filter. + init_pcap(argv[1], htons(cliAddr.sin_port)); + + // Open a file and pass the handle to the throughput sensor. + std::ofstream throughputStream; + + throughputStream.open("Throughput.log", std::ios::out); + + // Initialize the sensors. + packetSensor = new UdpPacketSensor(globalUdpState); + throughputSensor = new UdpThroughputSensor(globalUdpState, throughputStream); + maxDelaySensor = new UdpMaxDelaySensor(globalUdpState); + minDelaySensor = new UdpMinDelaySensor(globalUdpState); + + char packetData[1600]; + unsigned int curSeqNum = 0; + unsigned long long sendTime; + + // Timeout for the non-blocking socket reads and writes. + struct timeval selectTimeout; + + selectTimeout.tv_sec = 0; + selectTimeout.tv_usec = 5; + + FD_ZERO(&readFdSet); + FD_ZERO(&writeFdSet); + + // Change the socket descriptor to non-blocking. + flags = fcntl(sd, F_GETFL, 0); + flags = flags | O_NONBLOCK; + int readFlags = flags; + + // Set the socket descriptor to be non-blocking. + if( fcntl(sd, F_SETFL, flags) < 0) + { + printf("Error setting non blocking socket flags with fcntl.\n"); + exit(1); + } + + // Read the command line arguments. + // Number of packets, Size of the packets to be sent, and their sending rate. + packetCount = atoi(argv[4]); + unsigned long long lastSendTime = 0; + int packetLen = atoi(argv[5]); + long sendRate = atoi(argv[6]); + + int overheadLen = 20 + 8 + 14 + 4; + + long long timeInterval = 800000000 / sendRate; + timeInterval *= (packetLen + overheadLen); + timeInterval /= 100; + + lastSendTime = getTimeMicro(); + echoLen = sizeof(echoServAddr); + + /* send data */ + while(true) + { + if(curSeqNum < packetCount) + { + // UDP sends do not block - we don't need to + // check if the socket is ready for writing. + // FD_SET(sd, &writeFdSet); + + // select(1024,NULL,&writeFdSet, NULL,&selectTimeout); + + // if(FD_ISSET(sd, &writeFdSet) != 0) + { + + // This is used to regulate the rate + // at which we send data - once integrated, these + // intervals are sent to us from the application monitor. + + // For now, take a command line argument giving the rate + // at which UDP packets should be sent ( this rate includes + // the overhead for UDP, IP & ethernet headers ( ðernet checksum) + if(getTimeMicro() - lastSendTime > timeInterval) + { + curSeqNum++; + // Indicate that this is a data UDP packet - not an ACK. + packetData[0] = '0'; + + // Put the sequence number of the packet. + memcpy(&packetData[1],&curSeqNum, sizeof(unsigned int)); + + memcpy(&packetData[1 + sizeof(unsigned int)],&packetLen, sizeof(unsigned int)); + sendTime = getTimeMicro(); + lastSendTime = sendTime; + + rc = sendto(sd, packetData, packetLen, flags, + (struct sockaddr *) &remoteServAddr, + sizeof(remoteServAddr)); + + if(rc < 0) + { + printf("Blocked in send = %d\n",errno); + exit(1); + } + else + { + pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL); + } + } + } + + } + + // Check whether any data is available in the receive buffer + // for reading. + FD_SET(sd, &readFdSet); + + select(1024, &readFdSet, NULL, NULL,&selectTimeout); + + if(FD_ISSET(sd, &readFdSet) != 0) + { + n = recvfrom(sd, msg, MAX_MSG, 0, + (struct sockaddr *) &echoServAddr, &echoLen); + + if(n > 0) + pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL); + } + + + } + return 0; +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpLibs.h b/pelab/magent/UDP/UdpClientDir/UdpLibs.h new file mode 100644 index 0000000000000000000000000000000000000000..da37ed8c2b1b0907e06b1a163f03f54dbf41dae7 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpLibs.h @@ -0,0 +1,15 @@ +#ifndef UDPLIBS_PELAB_H +#define UDPLIBS_PELAB_H + +#include <iostream> +#include <fstream> +#include <vector> +#include <string> +#include <list> +#include <cstdlib> +#include <algorithm> +#include <functional> +#include <climits> +#include <limits.h> + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.cc b/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.cc new file mode 100644 index 0000000000000000000000000000000000000000..f8bda1438904d685d4f56da1ca57e38c29b9fc2e --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.cc @@ -0,0 +1,56 @@ +#include "UdpMaxDelaySensor.h" + +UdpMaxDelaySensor::UdpMaxDelaySensor(UdpState &udpStateVal) + : maxDelay(0), + udpStateInfo(udpStateVal) +{ + +} + + +void UdpMaxDelaySensor::localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp) +{ + +} + +void UdpMaxDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp) +{ + int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long); + unsigned long long tmpMaxDelay = maxDelay; + + if(Len < minSize) + { + cout << "Error: UDP packet data sent to MaxDelaySensor::localAck was less than the " + " required minimum "<< minSize << " bytes\n"; + return; + } + + int numRedunAcks = static_cast<int>(packetData[0]); + vector<UdpPacketInfo * >::iterator vecIterator; + unsigned int seqNum = *(unsigned int *)(packetData + 1); + unsigned long long oneWayDelay; + bool eventFlag = false; + + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum)); + + oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2; + + oneWayDelay = ( oneWayDelay )*1500 / (Len + 1); + + // Set this as the new maximum one way delay. + if(oneWayDelay > tmpMaxDelay) + { + eventFlag = true; + tmpMaxDelay = oneWayDelay; + } + + // Send an event message to the monitor to change the value of maximum one way delay. + maxDelay = tmpMaxDelay - udpStateInfo.minDelay; + if(udpStateInfo.packetLoss != 0 || eventFlag == true) + { + // Report the maximum delay + cout << "New Max Delay = " << maxDelay << "\n"; + } + + udpStateInfo.maxDelay = maxDelay; +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.h b/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.h new file mode 100644 index 0000000000000000000000000000000000000000..10118999ff89b86f2d2d16bdb1bdec3f60fb835a --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpMaxDelaySensor.h @@ -0,0 +1,22 @@ +#ifndef UDP_MAX_DELAY_SENSOR_PELAB_H +#define UDP_MAX_DELAY_SENSOR_PELAB_H + +#include "UdpLibs.h" +#include "UdpState.h" +#include "UdpSensor.h" + +class UdpSensor; + +class UdpMaxDelaySensor:public UdpSensor{ + public: + + explicit UdpMaxDelaySensor(UdpState &udpStateVal); + void localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + + private: + unsigned long long maxDelay; + UdpState &udpStateInfo; +}; + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.cc b/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.cc new file mode 100644 index 0000000000000000000000000000000000000000..df2ad9df898179c45664936a10082020d2029468 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.cc @@ -0,0 +1,92 @@ +#include "UdpMinDelaySensor.h" + +UdpMinDelaySensor::UdpMinDelaySensor(UdpState &udpStateVal) + : minDelay(ULONG_LONG_MAX), + udpStateInfo(udpStateVal) +{ + +} + + +void UdpMinDelaySensor::localSend(char *packetData, int Len,int overheadLen,unsigned long long timeStamp) +{ + // Do nothing. + +} + +void UdpMinDelaySensor::localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp) +{ + int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long); + + if(Len < minSize) + { + cout << "Error: UDP packet data sent to MinDelaySensor::localAck was less than the " + " required minimum "<< minSize << " bytes\n"; + return; + } + + int numRedunAcks = static_cast<int>(packetData[0]); + vector<UdpPacketInfo * >::iterator vecIterator; + unsigned int seqNum = *(unsigned int *)(packetData + 1); + unsigned long long oneWayDelay; + bool eventFlag = false; + + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum)); + + oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2; + long minDelayBytes = 0; + + // Calculate the delay for the maximum possibly sized packet. + oneWayDelay = ( oneWayDelay ) * 1500 / (Len + 1); + + // Set this as the new minimum one way delay. + if(oneWayDelay < minDelay) + { + eventFlag = true; + minDelay = oneWayDelay; + + // One byte was chopped off in the base sensor class. + // Add that to the packet length. + minDelayBytes = Len + 1; + } + + int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long); + int seqNumSize = sizeof(unsigned int); + + if(numRedunAcks > 0) + { + int i; + unsigned int redunSeqNum; + unsigned long timeDiff; + + for(i = 0;i < numRedunAcks; i++) + { + redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize); + timeDiff = *(unsigned long *)(packetData + minSize + i*redunAckSize + seqNumSize); + + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), redunSeqNum)); + + if(vecIterator != udpStateInfo.recentSentPackets.end()) + { + oneWayDelay = (timeStamp - timeDiff - (*vecIterator)->timeStamp ) /2; + oneWayDelay = ( oneWayDelay ) * 1500 / ( (*vecIterator)->packetSize ); + + if(oneWayDelay > 0 && oneWayDelay < minDelay) + { + eventFlag = true; + minDelay = oneWayDelay; + minDelayBytes = (*vecIterator)->packetSize; + } + } + } + + } + + // Send an event message to the monitor to change the value of minimum one way delay. + if(eventFlag == true) + { + cout << "New Min delay = " << minDelay << "\n"; + } + udpStateInfo.minDelay = minDelay; + udpStateInfo.minDelayBytes = minDelayBytes; +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.h b/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.h new file mode 100644 index 0000000000000000000000000000000000000000..70df9d9282148cf15ace4da7ec896052e91ad707 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpMinDelaySensor.h @@ -0,0 +1,22 @@ +#ifndef UDP_MIN_DELAY_SENSOR_PELAB_H +#define UDP_MIN_DELAY_SENSOR_PELAB_H + +#include "UdpLibs.h" +#include "UdpState.h" +#include "UdpSensor.h" + +class UdpSensor; + +class UdpMinDelaySensor:public UdpSensor{ + public: + + explicit UdpMinDelaySensor(UdpState &udpStateVal); + void localSend(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + + private: + unsigned long long minDelay; + UdpState &udpStateInfo; +}; + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.cc b/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..ddab272cf18d9cd77cde254dd85e4b50126ec9da --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.cc @@ -0,0 +1,11 @@ +#include "UdpPacketInfo.h" + +UdpPacketInfo::UdpPacketInfo(unsigned int seqVal, unsigned int packetSizeVal, unsigned long long timeStampVal, bool isFastPacketVal) + :seqNum(seqVal), + packetSize(packetSizeVal), + timeStamp(timeStampVal), + isFastPacket(isFastPacketVal), + lastTimeDiff(0) +{ + +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.h b/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..d6862d52c71fdb471389c928c6717c0b2a206736 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpPacketInfo.h @@ -0,0 +1,14 @@ +#ifndef UDP_PACKET_INFO_PELAB_H +#define UDP_PACKET_INFO_PELAB_H + +class UdpPacketInfo{ + public: + UdpPacketInfo::UdpPacketInfo(unsigned int, unsigned int, unsigned long long, bool); + unsigned int seqNum; + unsigned int packetSize; + unsigned long long timeStamp; + bool isFastPacket; + unsigned long long lastTimeDiff; +}; + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.cc b/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.cc new file mode 100644 index 0000000000000000000000000000000000000000..94984f4b5831382ab05fe1ae39a973d8e758c9ab --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.cc @@ -0,0 +1,166 @@ +#include "UdpPacketSensor.h" + +UdpPacketSensor::UdpPacketSensor(UdpState &udpStateVal) + :udpStateInfo(udpStateVal) +{ + lastPacketTime = 0; + + +} + +void UdpPacketSensor::localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp) +{ + int minSize = 2*sizeof(unsigned int); + if(Len < minSize) + { + cout << "Error: UDP packet data sent to PacketSensor::localSend was less than the " + " required minimum "<< minSize << " bytes\n"; + return; + } + unsigned int seqNum = *(unsigned int *)(packetData); + unsigned int packetSize = *(unsigned int *)(packetData + sizeof(unsigned int)); + bool isFastPacket = false; + unsigned long long sendTimeDelta = 0; + + if(lastPacketTime == 0) + lastPacketTime = timeStamp; + else + { + + sendTimeDelta = timeStamp - lastPacketTime; + lastPacketTime = timeStamp; + + if(sendTimeDelta < udpStateInfo.minDelay) + isFastPacket = 1; + + // We did not receive an ACK back, so we dont know the minimum + // one way delay. Treat all packets as fast packets until we + // find out the min. delay - this lowers the throughput a bit + // in case of packet loss if the packets were not being sent + // faster than min delay. + if(udpStateInfo.minDelay == 0) + isFastPacket = 1; + } + if(! sentPacketList.empty()) + sentPacketList.back()->lastTimeDiff = sendTimeDelta; + + sentPacketList.push_back(new UdpPacketInfo(seqNum, packetSize, timeStamp, isFastPacket)); +} + +void UdpPacketSensor::localAck(char *packetData, int Len, int overheadLen, unsigned long long timeStamp) +{ + int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long); + int i; + + // Remove the old state information. + for(i = 0;i < udpStateInfo.recentSentPackets.size(); i++) + delete udpStateInfo.recentSentPackets[i]; + udpStateInfo.recentSentPackets.clear(); + udpStateInfo.packetLoss = 0; + udpStateInfo.fastPacketLoss = 0; + udpStateInfo.lostPacketDelay = 0; + + udpStateInfo.lastSentTime = (ULONG_LONG_MAX); + + if(Len < minSize) + { + cout << "Error: UDP packet data sent to PacketSensor::localAck was less than the " + " minimum "<< minSize << " bytes\n"; + return; + } + + int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long); + + int numRedunAcks = static_cast<int>(packetData[0]); + + unsigned int seqNum = *(unsigned int *)(packetData + 1); + + // Find the entry for the packet this ACK is acknowledging, and + // remove it from the sent(&unacked) packet list. + list<UdpPacketInfo * >::iterator listIterator; + + listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(equalSeqNum(), seqNum)); + + if(listIterator == sentPacketList.end()) + { + cout << "ERROR: Unacked packet list is incorrect Or incorrect" + "acknowledgement received for seqNum = "<<seqNum<<" in PacketSensor::localAck\n"; + return; + } + + + // Store an iterator to the current seqNum being acknowledge, and delete it at the end. + list<UdpPacketInfo * >::iterator curPacketIterator = listIterator; + + // Look at the redundant ACKs first. + + if(numRedunAcks > 0) + { + unsigned int redunSeqNum; + + for(i = 0; i < numRedunAcks; i++) + { + redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize); + listIterator = sentPacketList.end(); + + // Check whether the packet that this redundant ACK refers to exists + // in our list of sent ( but unacked ) packets. It might not exist + // if its ACK was not lost earlier. + //listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(equalSeqNum(), redunSeqNum)); + listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(equalSeqNum(), redunSeqNum)); + + // An unacked packet exists with this sequence number, delete it + // from the list and consider it acked. + if(listIterator != curPacketIterator && listIterator != sentPacketList.end()) + { + udpStateInfo.recentSentPackets.push_back(new UdpPacketInfo((*listIterator)->seqNum, (*listIterator)->packetSize, (*listIterator)->timeStamp, (*listIterator)->isFastPacket) ); + + if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime) + udpStateInfo.lastSentTime = (*listIterator)->timeStamp; + + delete (*listIterator); + sentPacketList.erase(listIterator); + } + } + } + + udpStateInfo.recentSentPackets.push_back(new UdpPacketInfo((*curPacketIterator)->seqNum, (*curPacketIterator)->packetSize, (*curPacketIterator)->timeStamp, (*curPacketIterator)->isFastPacket)); + + // Check for packet loss - if we have any unacked packets with sequence + // numbers less than the received ACK seq number, then the packets/or their ACKS + // were lost - treat this as congestion on the forward path. + + // Find out how many packets were lost. + + listIterator = find_if(sentPacketList.begin(), sentPacketList.end(), bind2nd(lessSeqNum(), seqNum )); + + if(listIterator != sentPacketList.end()) + { + + do{ + if( (*listIterator)->timeStamp < udpStateInfo.lastSentTime) + udpStateInfo.lastSentTime = (*listIterator)->timeStamp; + + if( (*listIterator)->isFastPacket) + udpStateInfo.fastPacketLoss++; + + udpStateInfo.lostPacketDelay += (*listIterator)->lastTimeDiff; + + delete (*listIterator); + sentPacketList.erase(listIterator); + listIterator = sentPacketList.end(); + + udpStateInfo.packetLoss++; + + listIterator = find_if(sentPacketList.begin(), curPacketIterator, bind2nd(lessSeqNum(), seqNum )); + + } + while( (listIterator != sentPacketList.end()) && (listIterator != curPacketIterator) ); + + } + + if( (*curPacketIterator)->timeStamp < udpStateInfo.lastSentTime) + udpStateInfo.lastSentTime = (*curPacketIterator)->timeStamp; + delete (*curPacketIterator); + sentPacketList.erase(curPacketIterator); +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.h b/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..0687c373510ff9cb3f09766286775308909fb43e --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpPacketSensor.h @@ -0,0 +1,31 @@ +#ifndef UDP_PACKET_SENSOR_PELAB_H +#define UDP_PACKET_SENSOR_PELAB_H + +#include "UdpLibs.h" +#include "UdpState.h" +#include "UdpSensor.h" +#include "UdpPacketInfo.h" + +using namespace std; + +class UdpPacketInfo; +//class equalSeqNum; +class UdpSensor; + +class UdpPacketSensor:public UdpSensor{ + + public: + + explicit UdpPacketSensor(UdpState &udpStateVal); + void localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp); + void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + + private: + + list<UdpPacketInfo *> sentPacketList; + UdpState & udpStateInfo; + unsigned long long lastPacketTime; +}; + + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpSensor.cc b/pelab/magent/UDP/UdpClientDir/UdpSensor.cc new file mode 100644 index 0000000000000000000000000000000000000000..c35c90146bafcc325cc3e62401086b4560a7c922 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpSensor.cc @@ -0,0 +1,27 @@ +#include "UdpSensor.h" + +using namespace std; + +UdpSensor::UdpSensor() +{ + +} + +void UdpSensor::capturePacket(char *packetData, int Len, int overheadLen, unsigned long long timeStamp) +{ + if(Len < 1) + { + cout << "Error: UDP packet data sent to Sensor was less than " + " 1 byte in size\n"; + return; + } + + if(packetData[0] == '0') + { + localSend( (packetData+1), Len - 1,overheadLen, timeStamp ); + } + else if(packetData[0] == '1') + { + localAck( (packetData + 1), Len - 1,overheadLen, timeStamp ); + } +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpSensor.h b/pelab/magent/UDP/UdpClientDir/UdpSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..16952434260138971fbb1cfc3a309a4e8d395e15 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpSensor.h @@ -0,0 +1,14 @@ +#ifndef _UDP_SENSOR_PELAB_H +#define _UDP_SENSOR_PELAB_H + +#include "UdpLibs.h" + +class UdpSensor{ + public: + UdpSensor(); + virtual void localSend(char *packetData, int Len, int overheadLen,unsigned long long timeStamp)=0; + virtual void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp)=0; + void capturePacket(char *packetData, int Len, int overheadLen, unsigned long long timeStamp); +}; + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpState.h b/pelab/magent/UDP/UdpClientDir/UdpState.h new file mode 100644 index 0000000000000000000000000000000000000000..99afb8f60aeee5f72c82b958e8ba5a1b6ca1a3c1 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpState.h @@ -0,0 +1,46 @@ +#ifndef UDP_STATE_PELAB_H +#define UDP_STATE_PELAB_H + +#include "UdpLibs.h" +#include "UdpPacketInfo.h" + +using namespace std; + +class UdpPacketInfo; + +struct UdpState{ + // vector of info about packets sent from this host, + // sequence number, timestamp & size of the packet. + vector< UdpPacketInfo * > recentSentPackets; + + // Indicates the number of packets lost ( in a batch of 4 sent packets ) + // updated whenever an ACK is received. + int packetLoss, fastPacketLoss; + unsigned long long lastSentTime; + unsigned long long minDelay; + unsigned long long maxDelay; + unsigned long long minAckTimeDiff; + unsigned long long queuingDelay; + unsigned long long lostPacketDelay; + + long minDelayBytes; +}; + +class equalSeqNum:public binary_function<const UdpPacketInfo * , unsigned int, bool> { + public: + bool operator()(const UdpPacketInfo *packet, unsigned int seqNum) const + { + return (packet->seqNum == seqNum); + } +}; + +class lessSeqNum:public binary_function<const UdpPacketInfo *, int, bool> { + public: + bool operator()(const UdpPacketInfo *packet,unsigned int seqNum) const + { + return (packet->seqNum < seqNum); + } +}; + + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.cc b/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.cc new file mode 100644 index 0000000000000000000000000000000000000000..4719c2adcc73ffeca468c3cf83674653497b1b6f --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.cc @@ -0,0 +1,105 @@ +#include "UdpThroughputSensor.h" + +UdpThroughputSensor::UdpThroughputSensor(UdpState &udpStateVal, ofstream &outStreamVal) + : lastAckTime(-1), + throughputKbps(0.0), + udpStateInfo(udpStateVal), + outStream(outStreamVal) +{ + udpStateInfo.minAckTimeDiff = 999999999; + +} + +void UdpThroughputSensor::localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp) +{ + // Do nothing. + +} + +void UdpThroughputSensor::localAck(char *packetData, int Len, int overheadLen, unsigned long long timeStamp) +{ + int minSize = 1 + sizeof(unsigned int) + sizeof(unsigned long long); + + if(Len < minSize ) + { + cout << "Error: UDP packet data sent to ThroughputSensor::localAck was less than the " + " required minimum "<< minSize << " bytes\n"; + return; + } + + int redunAckSize = sizeof(unsigned int) + sizeof(unsigned long); + int seqNumSize = sizeof(unsigned int); + int numRedunAcks = static_cast<int>(packetData[0]); + + unsigned long long currentAckTimeStamp = *(unsigned long long *)(packetData + 1 + sizeof(unsigned int)); + + if(lastAckTime == -1) + { + lastAckTime = currentAckTimeStamp; + return; + } + + unsigned int seqNum; + seqNum = *(unsigned int *)(packetData + 1); + + unsigned long ackTimeDiff = currentAckTimeStamp - lastAckTime; + unsigned long timeDiff = 0; + vector<UdpPacketInfo * >::iterator vecIterator; + long dataSize = 0; + unsigned long long oneWayDelay = 0; + unsigned long long totalDelay = 0; + + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum)); + + //oneWayDelay = (timeStamp - (*vecIterator)->timeStamp)/2; + oneWayDelay = (timeStamp - udpStateInfo.lastSentTime)/2; + totalDelay = oneWayDelay; + + // Average the throughput over all the packets being acknowledged. + if(numRedunAcks > 0) + { + int i; + unsigned int redunSeqNum; + + for(i = 0;i < numRedunAcks; i++) + { + redunSeqNum = *(unsigned int *)(packetData + minSize + i*redunAckSize); + + // Find if this redundant ACK is useful - or it was acked before. + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), redunSeqNum)); + + if(vecIterator != udpStateInfo.recentSentPackets.end()) + { + // Calculate throughput for the packet being acked by + // the redundant ACK. + dataSize += (*vecIterator)->packetSize; + + } + + } + } + + vecIterator = find_if(udpStateInfo.recentSentPackets.begin(), udpStateInfo.recentSentPackets.end(), bind2nd(equalSeqNum(), seqNum)); + dataSize += ( (*vecIterator)->packetSize + overheadLen ); + + throughputKbps = 8000000.0*( static_cast<double> (dataSize )) / ( static_cast<double>(totalDelay)*1024.0 ); + + + if(udpStateInfo.packetLoss == 0) + { + // Send this available bandwidth as a tentative value. + // To be used for dummynet events only if it is greater + // than the last seen value. + cout << "Tentative bandwidth for seqNum = "<<seqNum<<", value = "<< throughputKbps <<", ackTimeDiff = "<<ackTimeDiff<<"\n"; + outStream << "TIME="<<timeStamp<<",TENTATIVE="<<throughputKbps<<endl; + + } + else + { + // Send this as the authoritative available bandwidth value. + cout << "Authoritative bandwidth for seqNum = "<<seqNum<<", value = "<< throughputKbps <<", ackTimeDiff ="<<ackTimeDiff<<"\n"; + outStream << "TIME="<<timeStamp<<",AUTHORITATIVE="<<throughputKbps<<endl; + } + + lastAckTime = currentAckTimeStamp; +} diff --git a/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.h b/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..8b58df14ef49bbf839c81c2261a8b937ad025724 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/UdpThroughputSensor.h @@ -0,0 +1,24 @@ +#ifndef UDP_THROUGHPUT_SENSOR_PELAB_H +#define UDP_THROUGHPUT_SENSOR_PELAB_H + +#include "UdpLibs.h" +#include "UdpState.h" +#include "UdpSensor.h" + +class UdpSensor; + +class UdpThroughputSensor:public UdpSensor{ + public: + + explicit UdpThroughputSensor(UdpState &udpStateVal, ofstream &outStreamVal); + void localSend(char *packetData, int Len, int overheadLen, unsigned long long timeStamp); + void localAck(char *packetData, int Len,int overheadLen, unsigned long long timeStamp); + + private: + long long lastAckTime; + double throughputKbps; + UdpState &udpStateInfo; + ofstream &outStream; +}; + +#endif diff --git a/pelab/magent/UDP/UdpClientDir/makeGnuPlot.py b/pelab/magent/UDP/UdpClientDir/makeGnuPlot.py new file mode 100755 index 0000000000000000000000000000000000000000..95d2289c0c76f70db956b2a9f79646bfcff9dba5 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/makeGnuPlot.py @@ -0,0 +1,36 @@ +import sys +import re + +inFile = open(sys.argv[1], 'r') + +outFile = open(sys.argv[2], 'w') + +regExp = re.compile('^(\w*?)\=(\d*)\,(\w*?)\=([\d\.]*)') + +count = 0 +availBandwidth = 0 +initTime = 0 +timeDiff = 0; +bandWidthBps = 0 + +for line in inFile: + match = regExp.match(line) + + if count == 0: + initTime = match.group(2) + timeDiff = 0 + count = count + 1 + else: + timeDiff = int(match.group(2)) - int(initTime) + + if match.group(3) == 'AUTHORITATIVE': + availBandwidth = float(match.group(4)) + elif match.group(3) == 'TENTATIVE': + if float(match.group(4)) > availBandwidth: + availBandwidth = float(match.group(4)) + + bandWidthBps = 1024*availBandwidth / ( 8 ) + + outFile.write(str(timeDiff) + " " + str(bandWidthBps) + "\n" ) + + diff --git a/pelab/magent/UDP/UdpClientDir/plot.gp b/pelab/magent/UDP/UdpClientDir/plot.gp new file mode 100644 index 0000000000000000000000000000000000000000..6c05a269703801ab68255bd4ce37f111f29b499e --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/plot.gp @@ -0,0 +1,5 @@ +set xlabel "Time( micro sec )" +set ylabel "Bandwidth( Bytes per sec )" + +plot 'Output.log' with lines + diff --git a/pelab/magent/UDP/UdpClientDir/runClient.sh b/pelab/magent/UDP/UdpClientDir/runClient.sh new file mode 100755 index 0000000000000000000000000000000000000000..33907793b54e082d6a1ba4fb6872617a2877c368 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/runClient.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Command line arguments: +# First argument - Interface on which we are connected to the server node ( not the control conn ). +# Second - Local IP address on the above interface. +# Third - Address/hostname of the node running the server program. +# Four - Number of UDP packets to send to the server. +# Five - Size of the data part of the UDP packets. +# Six - The rate at which the packets should be sent ( bits per sec ) +# This rate will also include the UDP, IP & ethernet headers along with the packet size. + +# The client runs in an infinite while loop - so when no more data is being printed on +# screen, it is safe to kill it( Ctrl-C) and look at the results. + +# NOTE: The UdpServer needs to be restarted before running the client for a second time. + +sudo ./UdpClient eth1 10.1.2.2 udpnode1 1000 958 4000000 diff --git a/pelab/magent/UDP/UdpClientDir/showTputGraph.sh b/pelab/magent/UDP/UdpClientDir/showTputGraph.sh new file mode 100755 index 0000000000000000000000000000000000000000..8a04ee4b193a6a8fdf5aad193c071f848a861273 --- /dev/null +++ b/pelab/magent/UDP/UdpClientDir/showTputGraph.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# UdpClient saves the throughput calculated after receiving each packet. + +# This data is dumped in Throughput.log - it is converted to a data file for GNUplot +# using a python script makeGnuPlot.py + +# The GNUplot file plot.gp displays the graph from data values in Output.log + +# NOTE: If you want to run the client multiple times, save the Output.log with +# another name, because it will be overwritten every time this shell script is run. + +python makeGnuPlot.py Throughput.log Output.log +gnuplot -persist plot.gp diff --git a/pelab/magent/UDP/UdpServerDir/Makefile.server b/pelab/magent/UDP/UdpServerDir/Makefile.server new file mode 100644 index 0000000000000000000000000000000000000000..948471079239b90c10f09cb2faf4dc9e412d1d0d --- /dev/null +++ b/pelab/magent/UDP/UdpServerDir/Makefile.server @@ -0,0 +1,8 @@ +EXECUTABLE=UdpServer + + +${EXECUTABLE}: UdpServer.cc + g++ -o $@ UdpServer.cc -lpcap + +clean: + rm -f ${EXECUTABLE} diff --git a/pelab/magent/UDP/UdpServerDir/Throughput.log b/pelab/magent/UDP/UdpServerDir/Throughput.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pelab/magent/UDP/UdpServerDir/UdpServer.cc b/pelab/magent/UDP/UdpServerDir/UdpServer.cc new file mode 100644 index 0000000000000000000000000000000000000000..8714e6ce8dfe1bb624836264ec815f523d9749fb --- /dev/null +++ b/pelab/magent/UDP/UdpServerDir/UdpServer.cc @@ -0,0 +1,487 @@ +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <sys/time.h> +#include <pcap.h> +#include <errno.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <netinet/if_ether.h> +#include <net/ethernet.h> +#include <netinet/ether.h> +#include <unistd.h> +#include <fcntl.h> + + +#define LOCAL_SERVER_PORT 1500 +#define MAX_MSG 1524 + +pcap_t *pcapDescriptor = NULL; + +struct udpAck{ + int seqNo; + unsigned long long ackTime; +}; + + +char appAck[2000]; +unsigned int curSeqNum = 0; +unsigned long long milliSec = 0; + +int queueStartPtr = -1; +int queueEndPtr = -1; +const int ackQueueSize = 3; +struct udpAck ackQueue[ackQueueSize]; + +int sd, rc, n, flags; +socklen_t cliLen; +struct sockaddr_in cliAddr, servAddr; +unsigned long long lastAckTime = 0; + +unsigned long long getPcapTimeMicro(const struct timeval *tp) +{ + unsigned long long tmpSecVal = tp->tv_sec; + unsigned long long tmpUsecVal = tp->tv_usec; + + return (tmpSecVal*1000*1000 + tmpUsecVal); +} + +// This is not used right now - only relevant if we are using SO_TIMESTAMP option instead +// of libpcap. +void handleUDPMsg(struct sockaddr_in *clientAddr, char *udpMessage, int messageLen, struct timeval *timeStamp, std::ofstream &fileHandle) +{ + /* + printf("Destination IP address = %s\n", inet_ntoa(ipPacket->ip_dst)); + printf("Source port = %d\n", ntohs(udpHdr->source)); + printf("Dest port = %d\n\n", ntohs(udpHdr->dest)); + */ + struct timeval timeVal; +// gettimeofday(&timeVal, NULL); + //std::cout << "Time before = "<<getPcapTimeMilli(&timeVal)<<std::endl; + + unsigned char packetType = udpMessage[0]; + unsigned long long milliSec = 0; + int ackLength = 0; + + if(packetType == '0') + { + // This is a udp data packet arriving here. Send an + // application level acknowledgement packet for it. + + // TODO:The packet can also be leaving from this host - our libpcap filter + // ignores those for now - as such, nothing needs to be done for such packets. + + unsigned int packetSeqNum = *(unsigned int *)(udpMessage + 1) ; + //printf("Data being received = %c, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1)); + + // If this sequence number is greater than the last sequence number + // we saw then send an acknowledgement for it. Otherwise, ignore the + // packet. + + // TODO:Take wrap around into account. + if(packetSeqNum > curSeqNum) + { + appAck[0] = '1'; + memcpy(&appAck[2], &packetSeqNum, sizeof(unsigned int)); + + milliSec = getPcapTimeMicro(timeStamp); + fileHandle << "Time="<<milliSec<<",Size="<<messageLen+20+8+14+4<<std::endl; + if(lastAckTime == 0) + lastAckTime = milliSec; + else + { + // std::cout << "Time of receive = "<<milliSec<<std::endl; + lastAckTime = milliSec; + } + + memcpy(&appAck[2 + sizeof(unsigned int)], &milliSec, sizeof(unsigned long long)); + + // Include the sequence numbers, and ACK times of the last + // seen three packets. + + // This condition holds only for the first ACK - means that + // there weren't any packets ACKed before this. + int numAcks; + unsigned long timeDiff = 0; + int ackSize = sizeof(unsigned int) + sizeof(unsigned long); + + if(queueStartPtr == -1 && queueEndPtr == -1) + { + // Do nothing. + numAcks = 0; + } + else if(queueStartPtr <= queueEndPtr) + numAcks = queueEndPtr - queueStartPtr + 1; + else + numAcks = 3; + + // Print a single digit number (0,1,2 or 3), indicating the + // number of redundant ACKs being sent. + appAck[1] = static_cast<char>(numAcks); + ackLength = numAcks*ackSize + sizeof(unsigned int) + sizeof(unsigned long long) + 2; + + int redunAckStart = 2 + sizeof(unsigned int) + sizeof(unsigned long long); + + // The ACK packet must be the same size as the original UDP + // packet that was received - this is needed so that the + // one way delay can be calculated as RTT/2. + if( messageLen > ackLength) + ackLength = messageLen; + + for(int i = 0;i < numAcks; i++) + { + memcpy(&appAck[redunAckStart + i*ackSize], &ackQueue[(queueStartPtr + i)%ackQueueSize].seqNo, sizeof(unsigned int)); + + + timeDiff = milliSec - ackQueue[(queueStartPtr + i)%ackQueueSize].ackTime; + // std::cout << "Timediff between redun = "<< ackQueue[ (queueStartPtr + i)%ackQueueSize].seqNo <<", and this = "<<timeDiff<<std::endl; + memcpy(&appAck[redunAckStart + i*ackSize + sizeof(unsigned int)], &timeDiff, sizeof(unsigned long)); + } + + // Always maintain the sequence numbers and ack send times + // of the last three ACK packets. + queueEndPtr = (queueEndPtr + 1)%ackQueueSize; + if(queueStartPtr != -1) + { + if(queueStartPtr == queueEndPtr) + queueStartPtr = (queueStartPtr + 1)%ackQueueSize; + } + else + queueStartPtr = 0; + + ackQueue[queueEndPtr].seqNo = packetSeqNum; + ackQueue[queueEndPtr].ackTime = milliSec; + + curSeqNum = packetSeqNum; + + sendto(sd,appAck,ackLength,flags,(struct sockaddr *)clientAddr,cliLen); + } + + } + else if(packetType == '1') + { + // TODO:This is an udp ACK packet. If it is being sent + // out from this host, do nothing. ( right now, this case does not + // occur, because our libpcap filter is only accepting incoming packets). + + // If we are receiving an ACK, pass it on to the sensors. + } + else + { + printf("ERROR: Unknown UDP packet received from remote agent\n"); + return; + } + +// gettimeofday(&timeVal, NULL); +// std::cout << "Time After = "<<getPcapTimeMicro(&timeVal)<<std::endl; +} + +void handleUDP(struct pcap_pkthdr const *pcap_info, struct udphdr const *udpHdr, u_char *const udpPacketStart, struct ip const *ipPacket) +{ + + u_char *dataPtr = udpPacketStart + 8; + unsigned short udpLen = ntohs(udpHdr->len); + + unsigned char packetType = *(unsigned char *)(dataPtr); + unsigned long long milliSec = 0; + int ackLength = 0; + + if(packetType == '0')// This is a udp data packet arriving here. Send an + // application level acknowledgement packet for it. + + // TODO:The packet can also be leaving from this host - the code for such packets + // is in the UdpClient application ( UdpClient.cc ). Once these changes + // are integrated into magent, then the functionality of this procedure + // will be a combination of code below and that in UdpClient. + { + unsigned int packetSeqNum = *(unsigned int *)(dataPtr + 1) ; + //printf("Data being received = %c, %u\n", *(unsigned char *)(dataPtr), *(unsigned int *)(dataPtr + 1)); + + // If this sequence number is greater than the last sequence number + // we saw then send an acknowledgement for it. Otherwise, ignore the + // packet. + + // TODO:Take wrap around into account. + if(packetSeqNum > curSeqNum) + { + appAck[0] = '1'; + memcpy(&appAck[2], &packetSeqNum, sizeof(unsigned int)); + + milliSec = getPcapTimeMicro(&pcap_info->ts); + if(lastAckTime == 0) + lastAckTime = milliSec; + else + { + lastAckTime = milliSec; + } + memcpy(&appAck[2 + sizeof(unsigned int)], &milliSec, sizeof(unsigned long long)); + + // Include the sequence numbers, and ACK times of the last + // seen three packets. + + // This condition holds only for the first ACK - means that + // there weren't any packets ACKed before this. + int numAcks; + unsigned long timeDiff = 0; + int ackSize = sizeof(unsigned int) + sizeof(unsigned long); + if(queueStartPtr == -1 && queueEndPtr == -1) + { + // Do nothing. + numAcks = 0; + } + else if(queueStartPtr <= queueEndPtr) + numAcks = queueEndPtr - queueStartPtr + 1; + else + numAcks = 3; + + // Print a single digit number (0,1,2 or 3), indicating the + // number of redundant ACKs being sent. + appAck[1] = static_cast<char>(numAcks); + ackLength = numAcks*ackSize + sizeof(unsigned int) + sizeof(unsigned long long) + 2; + + int redunAckStart = 2 + sizeof(unsigned int) + sizeof(unsigned long long); + + // The ACK packet must be the same size as the original UDP + // packet that was received - this is needed so that the + // one way delay can be calculated as RTT/2. + if( (udpLen - 8) > ackLength) + ackLength = udpLen - 8; + + for(int i = 0;i < numAcks; i++) + { + memcpy(&appAck[redunAckStart + i*ackSize], &ackQueue[(queueStartPtr + i)%ackQueueSize].seqNo, sizeof(unsigned int)); + + timeDiff = milliSec - ackQueue[(queueStartPtr + i)%ackQueueSize].ackTime; + memcpy(&appAck[redunAckStart + i*ackSize + sizeof(unsigned int)], &timeDiff, sizeof(unsigned long)); + } + + // Always maintain the sequence numbers and ack send times + // of the last three ACK packets. + queueEndPtr = (queueEndPtr + 1)%ackQueueSize; + if(queueStartPtr != -1) + { + if(queueStartPtr == queueEndPtr) + queueStartPtr = (queueStartPtr + 1)%ackQueueSize; + } + else + queueStartPtr = 0; + + ackQueue[queueEndPtr].seqNo = packetSeqNum; + ackQueue[queueEndPtr].ackTime = milliSec; + + curSeqNum = packetSeqNum; + + sendto(sd,appAck,ackLength,flags,(struct sockaddr *)&cliAddr,cliLen); + } + + } + else if(packetType == '1') // TODO:This is an udp ACK packet. If it is being sent + // out from this host, do nothing. ( right now, this case does not + // occur, because our libpcap filter is only accepting incoming packets). + + // If we are receiving an ACK, pass it on to the sensors. + { + + } + else + { + printf("ERROR: Unknown UDP packet received from remote agent\n"); + return; + } +} + +int getLinkLayer(struct pcap_pkthdr const *pcap_info, const u_char *pkt_data) +{ + unsigned int caplen = pcap_info->caplen; + + if (caplen < sizeof(struct ether_header)) + { + printf("A captured packet was too short to contain " + "an ethernet header"); + return -1; + } + else + { + struct ether_header * etherPacket = (struct ether_header *) pkt_data; + return ntohs(etherPacket->ether_type); + } +} + +void pcapCallback(u_char *user, const struct pcap_pkthdr *pcap_info, const u_char *pkt_data) +{ + int packetType = getLinkLayer(pcap_info, pkt_data); + + if(packetType != ETHERTYPE_IP) + { + printf("Unknown link layer type: %d\n", packetType); + return; + } + + struct ip const *ipPacket; + size_t bytesLeft = pcap_info->caplen - sizeof(struct ether_header); + + + if(bytesLeft < sizeof(struct ip)) + { + printf("Captured packet was too short to contain an IP header.\n"); + return; + } + + ipPacket = (struct ip const *)(pkt_data + sizeof(struct ether_header)); + int ipHeaderLength = ipPacket->ip_hl; + int ipVersion = ipPacket->ip_v; + + + if(ipVersion != 4) + { + printf("Captured IP packet is not IPV4.\n"); + return; + } + + if(ipHeaderLength < 5) + { + printf("Captured IP packet has header less than the minimum 20 bytes.\n"); + return; + } + + if(ipPacket->ip_p != IPPROTO_UDP) + { + printf("Captured packet is not a UDP packet.\n"); + return; + } + + // Ignore the IP options for now - but count their length. + ///////////////////////////////////////////////////////// + u_char *const udpPacketStart = (u_char *const)(pkt_data + sizeof(struct ether_header) + ipHeaderLength*4); + + struct udphdr const *udpPacket; + + udpPacket = (struct udphdr const *)udpPacketStart; + + bytesLeft -= ipHeaderLength*4; + + if(bytesLeft < sizeof(struct udphdr)) + { + printf("Captured packet is too small to contain a UDP header.\n"); + return; + } + + handleUDP(pcap_info,udpPacket,udpPacketStart, ipPacket); +} + + +void init_pcap(char *interface) +{ + struct bpf_program bpfProg; + char errBuf[PCAP_ERRBUF_SIZE]; + char filter[32] = ""; + + sprintf(filter," udp and dst port %d", ( LOCAL_SERVER_PORT ) ); + // IP Address and sub net mask. + bpf_u_int32 maskp, netp; + struct in_addr localAddress; + + + pcap_lookupnet(interface, &netp, &maskp, errBuf); + pcapDescriptor = pcap_open_live(interface, BUFSIZ, 0, 0, errBuf); + localAddress.s_addr = netp; + printf("IP addr = %s\n", inet_ntoa(localAddress)); + + if(pcapDescriptor == NULL) + { + printf("Error opening device %s with libpcap = %s\n", interface, errBuf); + exit(1); + } + + pcap_compile(pcapDescriptor, &bpfProg, filter, 1, netp); + pcap_setfilter(pcapDescriptor, &bpfProg); + + pcap_setnonblock(pcapDescriptor, 1, errBuf); +} + + +int main(int argc, char *argv[]) +{ + + char msg[MAX_MSG]; + + if(argc < 2) + { + printf("Usage: ./UdpServer interface_name\n"); + exit(1); + } + + /* socket creation */ + sd=socket(AF_INET, SOCK_DGRAM, 0); + + if(sd<0) + { + printf("%s: cannot open socket \n",argv[0]); + exit(1); + } + + /* bind local server port */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(LOCAL_SERVER_PORT); + rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr)); + + if(rc<0) + { + printf("%s: cannot bind port number %d \n", + argv[0], LOCAL_SERVER_PORT); + exit(1); + } + + printf("%s: waiting for data on port UDP %u\n", + argv[0],LOCAL_SERVER_PORT); + + init_pcap(argv[1]); + + flags = fcntl(sd, F_GETFL, 0); + + cliLen = sizeof(cliAddr); + + std::ofstream outFile; + + outFile.open("Throughput.log", std::ios::out); + + /* server infinite loop */ + while(true) + { + + /* receive message */ + n = recvfrom(sd, msg, MAX_MSG, flags, + (struct sockaddr *) &cliAddr, &cliLen); + + pcap_dispatch(pcapDescriptor, 1, pcapCallback, NULL); + + if(n<0) + { + printf("%s: cannot receive data \n",argv[0]); + continue; + } + + /* print received message */ + /* + printf("%s: from %s:UDP%u : %s \n", + argv[0],inet_ntoa(cliAddr.sin_addr), + ntohs(cliAddr.sin_port),msg); + */ + + + } + + return 0; + +} + diff --git a/pelab/magent/UDP/UdpServerDir/makeServerPlot.py b/pelab/magent/UDP/UdpServerDir/makeServerPlot.py new file mode 100755 index 0000000000000000000000000000000000000000..44ec58a8a4110914b54ba3b04521b1d47e81dfd0 --- /dev/null +++ b/pelab/magent/UDP/UdpServerDir/makeServerPlot.py @@ -0,0 +1,33 @@ +import sys +import re + +inFile = open(sys.argv[1], 'r') + +outFile = open(sys.argv[2], 'w') + +regExp = re.compile('^(\w*?)\=(\d*)\,(\w*?)\=(\d*)') + +count = 0 +bandWidth = 0 +initTime = 0 +timeDiff = 0; +lastTime = 0; +currentTime = 0; + +for line in inFile: + match = regExp.match(line) + + if count == 0: + initTime = int(match.group(2)) + timeDiff = 0 + count = count + 1 + lastTime = initTime + else: + currentTime = int(match.group(2)) + timeDiff = currentTime - initTime + bandWidth = int(match.group(4))*8000000 / ( ( currentTime - lastTime )*1024) + lastTime = currentTime + + outFile.write(str(timeDiff) + " " + str(bandWidth) + "\n" ) + + diff --git a/pelab/magent/UDP/UdpServerDir/plot.gp b/pelab/magent/UDP/UdpServerDir/plot.gp new file mode 100644 index 0000000000000000000000000000000000000000..affe51bf181a446ce431ab6bbf721fc0d1b3ac93 --- /dev/null +++ b/pelab/magent/UDP/UdpServerDir/plot.gp @@ -0,0 +1,5 @@ +set xlabel "Time( micro sec )" +set ylabel "Bandwidth( Kilo bits per sec )" + +plot [0:10000000] [0:20000] 'ServerOutput.log' with lines + diff --git a/pelab/magent/UDP/UdpServerDir/runServer.sh b/pelab/magent/UDP/UdpServerDir/runServer.sh new file mode 100755 index 0000000000000000000000000000000000000000..2f56f1f76118c01493632c965977e743dbdc6a09 --- /dev/null +++ b/pelab/magent/UDP/UdpServerDir/runServer.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# The argument below should be the interface on which this emulab node +# is connected to the other node ( running the client ) - not the +# control connection interface. + +# This can be looked up by running ifconfig and the interface with 10.*.*.* address +# is the correct one. + +# NOTE: A single invocation of file script/program only works for one UdpClient session. +# The server program has to be restarted for every session. + +# The server runs in an infinite while loop - it can be terminated after the session +# is determined to be done at the client - kill using Ctrl-C. + +sudo ./UdpServer eth1