diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -0,0 +1,75 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net" + "os" + "path/filepath" + "strings" + "sync" +) + +var wg sync.WaitGroup + +func Emit(pt Point) { + if pt == nil { + return + } + fmt.Println(pt) +} + +func DoHostfile(fname string) { + defer wg.Done() + hostname := filepath.Base(fname) + cfg, err := readConfigFile(fname) + if err != nil { + Emit(NewPoint("public", map[string]string{"host":hostname}, map[string]interface{}{"error": err.Error()})) + return + } + for _, address := range getAddresses(cfg) { + wg.Add(2) + go Emit(DoAddress(hostname, "tcp4", address)) + go Emit(DoAddress(hostname, "tcp6", address)) + } +} + +func DoAddress(host, network, address string) Point { + defer wg.Done() + tags := map[string]string{ + "host": host, + "network": network, + "address": address, + } + + addr, err := net.ResolveTCPAddr(network, address) + if err != nil { + if ae, ok := err.(*net.AddrError); ok && ae.Err == "no suitable address found" { + return nil + } + return NewPoint("public", tags, map[string]interface{}{"error": err.Error()}) + } + conn, err := net.DialTCP(network, nil, addr) + if err != nil { + return NewPoint("public", tags, map[string]interface{}{"error": err.Error()}) + } + conn.CloseWrite() + all, _ := ioutil.ReadAll(conn) + line := strings.TrimRight(string(all), "\n") + parts := strings.Split(line, " ") + if len(parts) != 3 { + return NewPoint("public", tags, map[string]interface{}{"error": fmt.Sprintf("malformed ID line: %q", line)}) + } + return NewPoint("public", tags, map[string]interface{}{ + "name": parts[1], + "version": parts[2], + }) +} + +func main() { + for _, fname := range os.Args[1:] { + wg.Add(1) + go DoHostfile(fname) + } + wg.Wait() +} |