1package main 2 3import ( 4 "fmt" 5 "log" 6 "os" 7 "path/filepath" 8 "time" 9 10 "git.torproject.org/user/phw/zoossh.git" 11) 12 13var processedCons int64 = 0 14var processedDescs int64 = 0 15var totalExits int64 = 0 16var totalRelays int64 = 0 17var totalBw uint64 = 0 18 19func Min(a uint64, b uint64, c uint64) uint64 { 20 21 min := a 22 23 if b < min { 24 min = b 25 } 26 27 if c < min { 28 min = c 29 } 30 31 return min 32} 33 34func ProcessDescriptors(path string, info os.FileInfo, err error) error { 35 36 if _, err := os.Stat(path); err != nil { 37 return err 38 } 39 40 if info.IsDir() { 41 return nil 42 } 43 44 consensus, err := zoossh.ParseDescriptorFile(path) 45 if err != nil { 46 return err 47 } 48 49 if (processedDescs % 100) == 0 { 50 fmt.Printf(".") 51 } 52 53 for _, getDesc := range consensus.RouterDescriptors { 54 desc := getDesc() 55 totalBw += Min(desc.BandwidthAvg, desc.BandwidthBurst, desc.BandwidthObs) 56 processedDescs++ 57 } 58 59 return nil 60} 61 62func ProcessConsensus(path string, info os.FileInfo, err error) error { 63 64 if _, err := os.Stat(path); err != nil { 65 return err 66 } 67 68 if info.IsDir() { 69 return nil 70 } 71 72 consensus, err := zoossh.ParseConsensusFile(path) 73 if err != nil { 74 return err 75 } 76 fmt.Printf(".") 77 78 for _, getStatus := range consensus.RouterStatuses { 79 status := getStatus() 80 totalRelays++ 81 if status.Flags.Exit == true { 82 totalExits++ 83 } 84 } 85 processedCons++ 86 87 return nil 88} 89 90func main() { 91 92 if len(os.Args) != 3 { 93 log.Fatalf("Usage: %s CONSENSUS_ARCHIVE DESCRIPTOR_ARCHIVE", os.Args[0]) 94 } 95 96 before := time.Now() 97 filepath.Walk(os.Args[1], ProcessConsensus) 98 fmt.Println() 99 after := time.Now() 100 101 duration := after.Sub(before) 102 fmt.Println("Total time for consensuses:", duration) 103 fmt.Printf("Time per consensus: %dms\n", 104 duration.Nanoseconds()/processedCons/int64(1000000)) 105 fmt.Printf("Processed %d consensuses with %d router status entries.\n", 106 processedCons, totalRelays) 107 fmt.Printf("Total exits: %d\n", totalExits) 108 109 before = time.Now() 110 filepath.Walk(os.Args[2], ProcessDescriptors) 111 fmt.Println() 112 after = time.Now() 113 114 duration = after.Sub(before) 115 fmt.Println("Total time for descriptors:", duration) 116 fmt.Printf("Time per descriptor: %dns\n", 117 duration.Nanoseconds()/processedDescs) 118 fmt.Printf("Processed %d descriptors.\n", processedDescs) 119 fmt.Printf("Average advertised bandwidth: %d\n", totalBw/uint64(processedDescs)) 120} 121