Skip to content

Instantly share code, notes, and snippets.

@benjojo
Last active April 26, 2017 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjojo/464fba6010686dd9afef2aa4c59a9d03 to your computer and use it in GitHub Desktop.
Save benjojo/464fba6010686dd9afef2aa4c59a9d03 to your computer and use it in GitHub Desktop.
DNS TTL blogpost
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"log"
"os"
"strconv"
"time"
)
type ProbeInfo struct {
ReportedTimes map[int64]TimeReport
UsedResolvers map[string]int
}
type TimeReport struct {
FirstSeen int
LastSeen int
}
type RipeData struct {
From string `json:"from"`
PrbID int `json:"prb_id"`
Resultset []struct {
Result struct {
Answers []struct {
NAME string `json:"NAME"`
RDATA []string `json:"RDATA"`
TYPE string `json:"TYPE"`
} `json:"answers"`
Rt float64 `json:"rt"`
Size float64 `json:"size"`
} `json:"result"`
Time float64 `json:"time"`
DstAddr string `json:"dst_addr"`
} `json:"resultset"`
Timestamp int `json:"timestamp"`
Type string `json:"type"`
}
func main() {
detailedmode := flag.Bool("detailed", false, "Print individual values")
csvmode := flag.Bool("csv", false, "Print results as CSV")
flag.Parse()
f, err := os.Open(flag.Arg(0))
if err != nil {
log.Fatalf("unable to open file, %s", err.Error())
}
probes := make(map[int]ProbeInfo)
reader := bufio.NewReader(f)
for {
lnb, _, err := reader.ReadLine()
if err != nil {
break
}
datapoint := RipeData{}
err = json.Unmarshal(lnb, &datapoint)
if err != nil {
log.Printf("Unable to decode data point %s", err.Error())
continue
}
if len(datapoint.Resultset) != 0 &&
len(datapoint.Resultset[0].Result.Answers) != 0 &&
len(datapoint.Resultset[0].Result.Answers[0].RDATA) != 0 {
i, err := strconv.ParseInt(datapoint.Resultset[0].Result.Answers[0].RDATA[0], 10, 64)
if err != nil {
continue
}
if probes[datapoint.PrbID].ReportedTimes == nil {
tmp := probes[datapoint.PrbID]
tmp.ReportedTimes = make(map[int64]TimeReport)
tmp.UsedResolvers = make(map[string]int)
probes[datapoint.PrbID] = tmp
}
probes[datapoint.PrbID].UsedResolvers[datapoint.Resultset[0].DstAddr]++
rt := probes[datapoint.PrbID].ReportedTimes
if rt[i].FirstSeen == 0 {
rttmp := TimeReport{}
rttmp.FirstSeen = datapoint.Timestamp
rt[i] = rttmp
} else if rt[i].LastSeen < datapoint.Timestamp {
rttmp := rt[i]
rttmp.LastSeen = datapoint.Timestamp
rt[i] = rttmp
} else if rt[i].FirstSeen > datapoint.Timestamp {
rttmp := rt[i]
rttmp.FirstSeen = datapoint.Timestamp
rt[i] = rttmp
}
}
}
if *csvmode {
fmt.Print("timeheld,probeid,resolvers\n")
}
for probeid, probedata := range probes {
if !(*csvmode) {
fmt.Printf("For Probe ID %d:\n", probeid)
fmt.Printf("Resolvers %v\n", probedata.UsedResolvers)
}
recordTime := 0.0
for timestamp, tsdata := range probedata.ReportedTimes {
if tsdata.LastSeen == 0 {
if *detailedmode {
fmt.Printf("\tFor value %d, never got cached\n", timestamp)
}
} else {
fs := time.Unix(int64(tsdata.FirstSeen), 0)
ls := time.Unix(int64(tsdata.LastSeen), 0)
between := ls.Sub(fs)
if *detailedmode {
fmt.Printf("\tFor value %d, was in cache for %f min\n", timestamp, between.Minutes())
}
if between.Minutes() > recordTime {
recordTime = between.Minutes()
}
}
}
if !(*csvmode) {
fmt.Printf("For Probe ID %d held on at best for %f min\n\n", probeid, recordTime)
} else {
fmt.Printf("%0.f,%d,%v\r\n", recordTime, probeid, probedata.UsedResolvers)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment