diff --git a/cmd/main.go b/cmd/main.go index 4ca185a..db54589 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,49 +10,14 @@ import ( flag "github.com/spf13/pflag" ) -func main() { - flag.IntVarP(&poolSize, "num_relays", "n", 100, `The number of concurrent relays tested.`) - flag.IntVarP(&goal, "working_relay_num_goal", "g", 5, `Test until at least this number of working relays are found`) - flag.StringVarP(&timeoutStr, "timeout", "t", "200ms", `Socket connection timeout`) - flag.StringVarP(&outfile, "outfile", "o", "", `Output reachable relays to file`) - flag.BoolVar(&torrc, "torrc", false, `Output reachable relays in torrc format (with "Bridge" prefix)`) - flag.StringArrayVarP(&urls, "url", "u", []string{}, `Preferred alternative URL for onionoo relay list. Could be used multiple times.`) - flag.StringArrayVarP(&port, "port", "p", []string{}, `Scan for relays running on specified port number. Could be used multiple times.`) - flag.BoolVarP(&ipv4, "ipv4", "4", false, `Use ipv4 only nodes`) - flag.BoolVarP(&ipv6, "ipv6", "6", false, `Use ipv6 only nodes`) - flag.BoolVarP(&jsonRelays, "json", "j", false, `Get available relays in json format`) - flag.BoolVarP(&silent, "silent", "s", false, `Silent mode`) - flag.StringVarP(&deadlineStr, "deadline", "d", "1m", `The deadline of program execution`) - flag.Usage = usage - flag.Parse() - - timeout, err := time.ParseDuration(timeoutStr) - if err != nil { - color.Errorf("cannot parse timeout duration: %s\n", err) - os.Exit(1) - } - - deadline, err := time.ParseDuration(deadlineStr) - if err != nil { - color.Errorf("cannot parse deadline duration: %s\n", err) - os.Exit(1) - } +var torRc, jsonRelays, silent bool +var outfile string - sc := scanner.New( - poolSize, - goal, - timeout, - outfile, - urls, - port, - ipv4, - ipv6, - silent, - deadline, - ) +func main() { + sc := create() var prefix string - if torrc { + if torRc { prefix = "Bridge " } @@ -87,7 +52,7 @@ func main() { for _, el := range relays { color.Fprintf(out, "%s%s %s\n", prefix, el.Address, el.Fingerprint) } - if torrc { + if torRc { color.Fprintf(out, "UseBridges 1\n") } } @@ -97,3 +62,61 @@ func usage() { flag.PrintDefaults() os.Exit(0) } + +func create() scanner.TorRelayScanner { + poolSize := flag.IntP("num_relays", "n", 100, `The number of concurrent relays tested.`) + goal := flag.IntP("working_relay_num_goal", "g", 5, `Test until at least this number of working relays are found`) + timeoutStr := flag.StringP("timeout", "t", "200ms", `Socket connection timeout`) + f := flag.StringP("outfile", "o", "", `Output reachable relays to file`) + t := flag.Bool("torrc", false, `Output reachable relays in torrc format (with "Bridge" prefix)`) + urls := flag.StringArrayP("url", "u", []string{}, `Preferred alternative URL for onionoo relay list. Could be used multiple times.`) + port := flag.StringArrayP("port", "p", []string{}, `Scan for relays running on specified port number. Could be used multiple times.`) + ipv4 := flag.BoolP("ipv4", "4", false, `Use ipv4 only nodes`) + ipv6 := flag.BoolP("ipv6", "6", false, `Use ipv6 only nodes`) + j := flag.BoolP("json", "j", false, `Get available relays in json format`) + s := flag.BoolP("silent", "s", false, `Silent mode`) + deadlineStr := flag.StringP("deadline", "d", "1m", `The deadline of program execution`) + flag.Usage = usage + flag.Parse() + + outfile = *f + torRc = *t + jsonRelays = *j + silent = *s + + timeout, err := time.ParseDuration(*timeoutStr) + if err != nil { + color.Printf("cannot parse timeout duration: %s\n", err) + os.Exit(1) + } + + if timeout < 50*time.Millisecond { + color.Println("It doesn't make sense to set a timeout of less than 50 ms") + os.Exit(1) + } + + deadline, err := time.ParseDuration(*deadlineStr) + if err != nil { + color.Printf("cannot parse deadline duration: %s\n", err) + os.Exit(1) + } + + if timeout > deadline { + color.Println("The deadline must be greater than the timeout") + os.Exit(1) + } + + sc := scanner.New( + *poolSize, + *goal, + timeout, + *urls, + *port, + *ipv4, + *ipv6, + silent, + deadline, + ) + + return sc +} diff --git a/cmd/models.go b/cmd/models.go deleted file mode 100644 index 1f5ffba..0000000 --- a/cmd/models.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -var ( - poolSize int - // Test until at least this number of working relays are found. default=5 - goal int - // Socket connection timeout. default=1s - timeoutStr string - // Output reachable relays to file. default=sys.stdout - outfile string - // Output reachable relays in torrc format (with "Bridge" prefix) - torrc bool - // Preferred alternative URL for onionoo relay list. Could be used multiple times - urls []string - // Scan for relays running on specified port number. Could be used multiple times - port []string - // Use ipv4 only nodes - ipv4 bool - // Use ipv6 only nodes - ipv6 bool - // Get available relays in json format - jsonRelays bool - // Silent mode - silent bool - // Deadline - deadlineStr string -) diff --git a/models.go b/models.go index 09aabb8..59a100f 100644 --- a/models.go +++ b/models.go @@ -18,8 +18,6 @@ type torRelayScanner struct { goal int // Socket connection timeout. default=1s timeout time.Duration - // Output reachable relays to file. default=sys.stdout - outfile string // Preferred alternative URL for onionoo relay list. Could be used multiple times urls []string // Scan for relays running on specified port number. Could be used multiple times diff --git a/scanner.go b/scanner.go index 028cffe..991e9f7 100644 --- a/scanner.go +++ b/scanner.go @@ -25,7 +25,6 @@ func New( poolSize int, goal int, timeout time.Duration, - outfile string, urlsList []string, port []string, ipv4 bool, @@ -52,7 +51,6 @@ func New( poolSize: poolSize, goal: goal, timeout: timeout, - outfile: outfile, urls: urls, ports: port, ipv4: ipv4, @@ -120,7 +118,6 @@ func (t *torRelayScanner) getRelays() Relays { }) } p.Wait() - close(chanRelays) }() bar := progressbar.NewOptions( @@ -153,7 +150,8 @@ func (t *torRelayScanner) getRelays() Relays { relays = append(relays, el) _ = bar.Add(1) case <-ctx.Done(): - color.Fprintf(os.Stderr, "\nThe program was running for more than the specified time: %.0fm", t.deadline.Minutes()) + _ = bar.Add(t.goal) + color.Fprintf(os.Stderr, "\nThe program was running for more than the specified time: %.2fm", t.deadline.Minutes()) os.Exit(1) } } @@ -247,7 +245,8 @@ func (t *torRelayScanner) grab(addr string) (RelayInfo, error) { // tcpSocketConnectChecker just checked network connection with specific host:port func tcpSocketConnectChecker(addr string, timeout time.Duration) bool { - _, err := net.DialTimeout("tcp", addr, timeout) + d := net.Dialer{Deadline: time.Now().Add(timeout)} + _, err := d.Dial("tcp", addr) return err == nil }