-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
67 lines (60 loc) · 1.35 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Lookup looks up IP addresses concurrently. Hosts are supplied as STDIN stream.
// Adapted from https://youtu.be/woCg2zaIVzQ.
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
"sync"
)
type lookup struct {
host string
addrs []string
err error
}
func main() {
hosts := make(chan string)
lookups := make(chan lookup)
var wg sync.WaitGroup
// Read lines from stdin and stuff them down the hosts channel.
wg.Add(1)
go func() {
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
hosts <- input.Text()
}
if err := input.Err(); err != nil {
fmt.Fprintf(os.Stderr, "lookup: %v\n", err)
os.Exit(1)
}
close(hosts)
wg.Done()
}()
// Spin up 1000 goroutines doing lookups on lines coming out of the
// hosts channel and stuffing the results down the lookups channel.
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
for host := range hosts {
addrs, err := net.LookupHost(host)
lookups <- lookup{host: host, addrs: addrs, err: err}
}
wg.Done()
}()
}
// Wait until stdin is closed and all lookups are done.
go func() {
wg.Wait()
close(lookups)
}()
// Print errors on stderr and lookups on stdout.
for lookup := range lookups {
if lookup.err != nil {
fmt.Fprintf(os.Stderr, "lookup: %v\n", lookup.err)
} else {
fmt.Printf("%s: %s\n", lookup.host, strings.Join(lookup.addrs, ", "))
}
}
}