def readOneTraceroute(trace, diffRtt, metric=np.nanmedian): """Read a single traceroute instance and compute the corresponding differential RTTs. """ if trace is None or "error" in trace["result"][0] or "err" in trace["result"][0]["result"]: return diffRtt # probeId = "probe_%s" % trace["prb_id"] probeIp = trace["from"] prevRttMed = {} for hopNb, hop in enumerate(trace["result"]): # print "i=%s and hop=%s" % (hopNb, hop) try: # TODO: clean that workaround results containing no IP, e.g.: # {u'result': [{u'x': u'*'}, {u'x': u'*'}, {u'x': u'*'}], u'hop': 6}, if "result" in hop : rttList = defaultdict(list) rttMed = {} for res in hop["result"]: if not "from" in res or tools.isPrivateIP(res["from"]) or not "rtt" in res or res["rtt"] <= 0.0: continue # assert hopNb+1==hop["hop"] or hop["hop"]==255 rttList[res["from"]].append(res["rtt"]) for ip2, rtts in rttList.iteritems(): rttAgg = np.median(rtts) rttMed[ip2] = rttAgg # Differential rtt if len(prevRttMed): for ip1, pRttAgg in prevRttMed.iteritems(): if ip1 == ip2 : continue # data for (ip1, ip2) and (ip2, ip1) are put # together in mergeRttResults if (ip1, ip2) in diffRtt: i = diffRtt[(ip1,ip2)] i["rtt"].append(rttAgg-pRttAgg) i["probe"].append(probeIp) else: diffRtt[(ip1,ip2)] = {"rtt": [rttAgg-pRttAgg], "probe": [probeIp]} finally: prevRttMed = rttMed # TODO we miss 2 inferred links if a router never replies return diffRtt
def traceroute2timetrack(self, trace): """Read a single traceroute result and get rtts for each AS """ if "prb_id" not in trace: logging.warning("No probe ID given: %s" % trace) return None # Check if the traceroute is valid if trace is None or "error" in trace["result"][0] or "err" in trace[ "result"][0]["result"]: return None probe_asn = self.i2a.ip2asn(trace["from"]) if (trace.get( "from", "")) else "Unk" timetrack = { "prb_id": "PB" + str(trace["prb_id"]), "from_asn": probe_asn, "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } for hopNb, hop in enumerate(trace["result"]): if "result" in hop: router_ip = "" for res in hop["result"]: if not "from" in res or tools.isPrivateIP( res["from"] ) or not "rtt" in res or res["rtt"] <= 0.0: continue if res["from"] != router_ip: router_ip = res["from"] router_asn = self.i2a.ip2asn(router_ip) if router_asn < 0: router_asn = "IX" + str(router_asn * -1) else: router_asn = "AS" + str(router_asn) # if router_asn == "unknown": # router_asn = router_ip idx = -1 if len(timetrack["rtts"] ) == 0 or timetrack["rtts"][idx][0] != router_asn: if len(timetrack["rtts"]) > 1 and timetrack["rtts"][ idx - 1][0] == router_asn: idx -= 1 else: timetrack["rtts"].append((router_asn, [])) timetrack["rtts"][idx][1].append(res["rtt"]) return timetrack
def traceroute2timetrack(self, trace): """Read a single traceroute result and get rtts for the destination city """ if "prb_id" not in trace: logging.warning("No probe ID given: %s" % trace) return None # Check if the traceroute is valid if trace is None or "error" in trace["result"][0] or "err" in trace[ "result"][0]["result"]: return None probe_asn = self.i2a.ip2asn(trace["from"]) if (trace.get( "from", "")) else "Unk (PB{})".format(trace["prb_id"]) timetrack = { "prb_id": "PB" + str(trace["prb_id"]), "from_asn": probe_asn, "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } source_city = self.anchor_info[trace["from"]]["city"] if trace[ "from"] in self.anchor_info else "Unk" timetrack["rtts"].append((source_city, [0])) hop = trace["result"][-1] if "result" not in hop: return None dest_city = self.anchor_info[trace["dst_addr"]]["city"] if trace[ "dst_addr"] in self.anchor_info else "Unk" timetrack["rtts"].append((dest_city, [])) no_rtt = True for res in hop["result"]: if not "from" in res or tools.isPrivateIP(res["from"]) \ or not "rtt" in res or res["rtt"] <= 0.0 \ or res["from"] != trace["dst_addr"]: continue no_rtt = False timetrack["rtts"][-1][1].append(res["rtt"]) if no_rtt: return None else: return timetrack
def readOneTraceroute(trace, routes): """Read a single traceroute instance and compute the corresponding routes. """ if trace is None or not "dst_addr" in trace or "error" in trace["result"][ 0] or "err" in trace["result"][0]["result"]: return probeIp = trace["from"] dstIp = trace["dst_addr"] listRouter = routes[dstIp] prevIps = [probeIp] * 3 currIps = [] if "prb_id" in trace: probeId = trace["prb_id"] if "msm_id" in trace: msmId = trace["msm_id"] for hop in trace["result"]: if "result" in hop: for resNb, res in enumerate(hop["result"]): # In case of routers not sending ICMP or packet loss, result # looks like: # {u'result': [{u'x': u'*'}, {u'x': u'*'}, {u'x': u'*'}], u'hop': 6}, if not "from" in res: ip = "x" elif tools.isPrivateIP(res["from"]): continue else: ip = res["from"] nbPrevIps = float(len(prevIps)) for prevIp in prevIps: if not ip in listRouter[prevIp]: listRouter[prevIp][ip] = defaultdict(int) listRouter[prevIp][ip]["msm"] = defaultdict(set) listRouter[prevIp][ip][probeIp] += 1 / nbPrevIps listRouter[prevIp][ip]["msm"][msmId].add(probeId) currIps.append(ip) if currIps: prevIps = currIps currIps = []
def readOneTraceroute(trace, routes): """Read a single traceroute instance and compute the corresponding routes. """ if trace is None or not "dst_addr" in trace or "error" in trace["result"][0] or "err" in trace["result"][0]["result"]: return probeIp = trace["from"] dstIp = trace["dst_addr"] listRouter = routes[dstIp] prevIps = [probeIp]*3 currIps = [] for hop in trace["result"]: if "result" in hop : for resNb, res in enumerate(hop["result"]): # In case of routers not sending ICMP or packet loss, result # looks like: # {u'result': [{u'x': u'*'}, {u'x': u'*'}, {u'x': u'*'}], u'hop': 6}, if not "from" in res: ip = "x" elif tools.isPrivateIP(res["from"]): continue else: ip = res["from"] for prevIp in prevIps: if ip in listRouter[prevIp]: listRouter[prevIp][ip].append(probeIp) else: listRouter[prevIp][ip] = [probeIp] currIps.append(ip) if currIps: prevIps = currIps currIps = []
def readOneTracerouteAllSigna(trace, diffRtt, metric=np.nanmedian): """Read a single traceroute instance and compute the corresponding differential RTTs. """ traceroute=[element.encode('ascii', 'ignore') for element in trace] data=str(trace[3].encode('ascii', 'ignore')) entry = data.replace("=", ":") data = json.loads(entry.decode('string-escape').strip('"')) if len(data) ==0: return diffRtt probeIp = str(trace[0].encode('ascii', 'ignore')) probeId = int(trace[1].encode('ascii', 'ignore')) msmId = str(trace[2].encode('ascii', 'ignore')) if probeId is not None: probeId = int(trace[1].encode('ascii', 'ignore')) else: probeId =None if msmId is not None: msmId = str(trace[2].encode('ascii', 'ignore')) else: msmId=None prevRttMed = {} #print('data ',data) for hopNb, hop in enumerate(data): try: # TODO: clean that workaround results containing no IP, e.g.: # {u'result': [{u'x': u'*'}, {u'x': u'*'}, {u'x': u'*'}], u'hop': 6}, rttList = defaultdict(list) rttMed = {} for element in hop: ipadress = element.keys()[0] rtt = element[ipadress] if tools.isPrivateIP(ipadress) or rtt <= 0.0 : continue # assert hopNb+1==hop["hop"] or hop["hop"]==255 rttList[ipadress].append(rtt) for ip2, rtts in rttList.iteritems(): rttAgg = np.median(rtts) rttMed[ip2] = rttAgg # Differential rtt if len(prevRttMed): for ip1, pRttAgg in prevRttMed.iteritems(): if ip1 == ip2 : continue # data for (ip1, ip2) and (ip2, ip1) are put # together in mergeRttResults if not (ip1, ip2) in diffRtt: diffRtt[(ip1,ip2)] = {"rtt": [], "probe": [], "msmId": defaultdict(set) } i = diffRtt[(ip1,ip2)] i["rtt"].append(rttAgg-pRttAgg) i["probe"].append(probeIp) i["msmId"][msmId].add(probeId) finally: prevRttMed = rttMed # TODO we miss 2 inferred links if a router never replies return diffRtt
def readOneTraceroute(trace, diffRtt, metric=np.nanmedian): """Read a single traceroute instance and compute the corresponding differential RTTs. """ if trace is None or "error" in trace["result"][0] or "err" in trace[ "result"][0]["result"]: return diffRtt probeIp = trace["from"] probeId = None msmId = None if "prb_id" in trace: probeId = trace["prb_id"] if "msm_id" in trace: msmId = trace["msm_id"] prevRttMed = {} for hopNb, hop in enumerate(trace["result"]): try: # TODO: clean that workaround results containing no IP, e.g.: # {u'result': [{u'x': u'*'}, {u'x': u'*'}, {u'x': u'*'}], u'hop': 6}, if "result" in hop: rttList = defaultdict(list) rttMed = {} for res in hop["result"]: if not "from" in res or tools.isPrivateIP( res["from"] ) or not "rtt" in res or res["rtt"] <= 0.0: continue # assert hopNb+1==hop["hop"] or hop["hop"]==255 rttList[res["from"]].append(res["rtt"]) for ip2, rtts in rttList.iteritems(): rttAgg = np.median(rtts) rttMed[ip2] = rttAgg # Differential rtt if len(prevRttMed): for ip1, pRttAgg in prevRttMed.iteritems(): if ip1 == ip2: continue # data for (ip1, ip2) and (ip2, ip1) are put # together in mergeRttResults if not (ip1, ip2) in diffRtt: diffRtt[(ip1, ip2)] = { "rtt": [], "probe": [], "msmId": defaultdict(set) } i = diffRtt[(ip1, ip2)] i["rtt"].append(rttAgg - pRttAgg) i["probe"].append(probeIp) i["msmId"][msmId].add(probeId) finally: prevRttMed = rttMed # TODO we miss 2 inferred links if a router never replies return diffRtt
def traceroute2timetrack(self, trace): """Read a single traceroute result and get rtts for the destination city """ # Check if the traceroute is valid if "prb_id" not in trace or trace is None or "error" in trace[ "result"][0] or "err" in trace["result"][0]["result"]: return None prb_id = str(trace["prb_id"]) prb_ip = trace.get("from", "") asn_str = "asn_v" + str(trace["af"]) try: probe = self.probe_info[prb_ip] except KeyError: probe = self.probe_info.setdefault(prb_ip, { asn_str: self.i2a.ip2asn(prb_ip) if prb_ip else "Unk PB" + prb_id }) # Initialisation of the timetrack timetrack = { "prb_id": "PB" + prb_id, "from_asn": probe[asn_str], "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } if "city" in probe: timetrack["rtts"].append((probe["city"], [0])) for hopNb, hop in enumerate(trace["result"]): if "result" in hop: router_ip = "" router_asn = "" for res in hop["result"]: if not "from" in res or not "rtt" in res or res[ "rtt"] <= 0.0: continue if res["from"] != router_ip: router_ip = res["from"] if tools.isPrivateIP(router_ip): continue router_asn = self.i2a.ip2asn(router_ip) if router_asn < 0: router_asn = "IX" + str(router_asn * -1) else: router_asn = "AS" + str(router_asn) # if router_asn == "unknown": # router_asn = router_ip idx = -1 if len(timetrack["rtts"] ) == 0 or timetrack["rtts"][idx][0] != router_asn: if len(timetrack["rtts"]) > 1 and timetrack["rtts"][ idx - 1][0] == router_asn: idx -= 1 else: timetrack["rtts"].append((router_asn, [])) timetrack["rtts"][idx][1].append(res["rtt"]) if router_ip == trace["dst_addr"] and trace[ "dst_addr"] in self.probe_info: dest_city = self.probe_info[ trace["dst_addr"]]["city"] if trace[ "dst_addr"] in self.probe_info else "Unk" timetrack["rtts"].append( (dest_city, timetrack["rtts"][idx][1])) return timetrack
def traceroute2timetrack(self, trace): """Read a single traceroute result and get rtts for the first public hop""" found_first_hop = False if "prb_id" not in trace or "result" not in trace: logging.warning("No probe ID or result given: %s" % trace) return None af = trace.get('af', 4) # last-mile detection works only in IPv4 if af != 4: return None asn_str = "asn_v" + str(af) ip_space_str = "v" + str(af) prb_id = str(trace["prb_id"]) prb_ip = trace.get("from", "") try: probe = self.probe_info[prb_id] timetrack = { "prb_id": "PB" + prb_id, "from_asn": "".join(["AS", str(probe[asn_str]), ip_space_str]), "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } except KeyError: if prb_id not in self.probe_info: probe = self.probe_info.setdefault(prb_id, { asn_str: "AS"+str(self.i2a.ip2asn(prb_ip)) \ if prb_ip else "Unk PB"+prb_id, "location": "PB"+prb_id }) self.probe_info[prb_id] = probe elif asn_str not in probe: probe[asn_str] = "AS"+str(self.i2a.ip2asn(prb_ip)) \ if prb_ip else "Unk PB"+prb_id timetrack = { "prb_id": "PB" + prb_id, "from_asn": "".join(["AS", str(probe[asn_str]), ip_space_str]), "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } timetrack["rtts"].append([probe["location"] + ip_space_str, [0]]) prev_hop_rtt = None curr_hop_rtt = [0] for hopNb, hop in enumerate(trace["result"]): if len(curr_hop_rtt): prev_hop_rtt = curr_hop_rtt curr_hop_rtt = [] if "result" in hop: router_ip = "" for res in hop["result"]: if not "from" in res or not "rtt" in res or res[ "rtt"] <= 0.0: continue if tools.isPrivateIP(res["from"]): curr_hop_rtt.append(res["rtt"]) continue found_first_hop = True router_ip = res["from"] router_asn = str(self.i2a.ip2asn(router_ip)) # router IP might not be announced on BGP if router_asn == '0' or router_asn is None: if isinstance(probe[asn_str], int): router_asn = str(probe[asn_str]) elif isinstance( probe[asn_str], str) and probe[asn_str].startswith('AS'): router_asn = probe[asn_str][2:] else: return None # check that router ASN is same as the probe elif router_asn != str(probe[asn_str]).rpartition('AS')[2]: return None location_str = "".join(["LM", router_asn, ip_space_str]) if len(timetrack["rtts"] ) == 0 or timetrack["rtts"][-1][0] != location_str: timetrack["rtts"].append((location_str, [])) timetrack["rtts"][-1][1].append(res["rtt"]) if found_first_hop: # Replace probes rtt by the previous hop RTT # That mean we will compute last mile delay only, # avoiding delay on the home/private network timetrack["rtts"][0][1] = prev_hop_rtt return timetrack return None
def traceroute2timetrack(self, trace): """Read a single traceroute result and get rtts for the first public hop""" found_first_hop = False if "prb_id" not in trace: logging.warning("No probe ID given: %s" % trace) return None asn_str = "asn_v" + str(trace["af"]) ip_space_str = "v" + str(trace["af"]) prb_id = str(trace["prb_id"]) prb_ip = trace.get("from", "") try: probe = self.probe_info[prb_id] timetrack = { "prb_id": "PB" + prb_id, "from_asn": "".join(["AS", str(probe[asn_str]), ip_space_str]), "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } except KeyError: if prb_id not in self.probe_info: probe = self.probe_info.setdefault(prb_id, { asn_str: "AS"+str(self.i2a.ip2asn(prb_ip)) \ if prb_ip else "Unk PB"+prb_id, "location": "|".join("PB"+prb_id, "PF"+probe["prefix_v4"]) }) self.probe_info[prb_id] = probe elif asn_str not in probe: probe[asn_str] = "AS"+str(self.i2a.ip2asn(prb_ip)) \ if prb_ip else "Unk PB"+prb_id timetrack = { "prb_id": "PB" + prb_id, "from_asn": "".join(["AS", str(probe[asn_str]), ip_space_str]), "msm_id": trace["msm_id"], "timestamp": trace["timestamp"], "rtts": [] } timetrack["rtts"].append([probe["location"], [0]]) prev_hop_rtt = None curr_hop_rtt = [0] for hopNb, hop in enumerate(trace["result"]): if len(curr_hop_rtt): prev_hop_rtt = curr_hop_rtt curr_hop_rtt = [] if "result" in hop: router_ip = "" for res in hop["result"]: if not "from" in res or not "rtt" in res or res[ "rtt"] <= 0.0: continue if tools.isPrivateIP(res["from"]): curr_hop_rtt.append(res["rtt"]) continue found_first_hop = True if res["from"] != router_ip: router_ip = res["from"] router_asn = str(self.i2a.ip2asn(router_ip)) location_str = "".join( ["AS", str(router_asn), ip_space_str]) if len(timetrack["rtts"] ) == 0 or timetrack["rtts"][-1][0] != location_str: timetrack["rtts"].append((location_str, [])) timetrack["rtts"][-1][1].append(res["rtt"]) if found_first_hop: # Replace probes rtt by the previous hop RTT # That mean we will compute last mile delay only, # avoiding delay on the home/private network timetrack["rtts"][0][1] = prev_hop_rtt return timetrack