-
Notifications
You must be signed in to change notification settings - Fork 119
/
netdial.go
99 lines (90 loc) · 3.03 KB
/
netdial.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
* Copyright 2019 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package inputs
import (
"bufio"
"context"
"fmt"
"net"
"net/textproto"
"time"
"github.com/newrelic/nri-flex/internal/load"
)
// NetDialWithTimeout performs network dial without timeout
func NetDialWithTimeout(dataStore *[]interface{}, command load.Command, dataSample *map[string]interface{}, api load.API, processType *string) {
ctx := context.Background()
// Create a channel for signal handling
c := make(chan struct{})
// Define a cancellation after default dial timeout in the context
timeout := load.DefaultDialTimeout // ms
if api.Timeout > 0 {
timeout = api.Timeout
}
if command.Timeout > 0 {
timeout = command.Timeout
}
ctx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Millisecond)
defer cancel()
addr := command.Dial
netw := "tcp"
if command.Network != "" {
netw = command.Network
}
var dialError error
var data string
// Run dial via a goroutine
load.Logrus.Debugf("commands: dialling %v : %v", addr, netw)
dialConn, err := net.DialTimeout(netw, addr, time.Duration(timeout)*time.Millisecond)
if err == nil {
defer dialConn.Close()
}
go func(dialConn net.Conn, err error) {
if err != nil {
dialError = err
} else {
if command.Run != "" {
fmt.Fprintf(dialConn, command.Run)
reader := bufio.NewReader(dialConn)
tp := textproto.NewReader(reader)
for {
select {
case <-ctx.Done():
return
default:
line, _ := tp.ReadLine()
data += line + "\n"
}
}
}
}
c <- struct{}{}
}(dialConn, err)
// Listen for signals
select {
case <-ctx.Done():
if command.Run == "" {
*dataStore = append(*dataStore, map[string]interface{}{"portStatus": "closed", "addr": command.Dial, "netw": netw, "err": ctx.Err().Error()})
// load.StoreAppend(map[string]interface{}{"portStatus": "closed", "addr": command.Dial, "netw": netw, "err": ctx.Err().Error()})
} else if command.Run != "" && data != "" {
processOutput(dataStore, data, dataSample, command, api, processType)
}
if data == "" {
load.Logrus.Error("commands: dial " + ctx.Err().Error())
} else {
load.Logrus.Debug("commands: dial " + ctx.Err().Error())
}
case <-c:
if command.Run == "" && dialError == nil {
*dataStore = append(*dataStore, map[string]interface{}{"portStatus": "open", "addr": command.Dial, "netw": netw})
// load.StoreAppend(map[string]interface{}{"portStatus": "open", "addr": command.Dial, "netw": netw})
} else if command.Run == "" && dialError != nil {
*dataStore = append(*dataStore, map[string]interface{}{"portStatus": "closed", "addr": command.Dial, "netw": netw, "err": dialError.Error()})
// load.StoreAppend(map[string]interface{}{"portStatus": "closed", "addr": command.Dial, "netw": netw, "err": dialError.Error()})
} else if command.Run != "" && dialError == nil && data != "" {
processOutput(dataStore, data, dataSample, command, api, processType)
}
load.Logrus.Debugf("commands: finished dial %v : %v", command.Dial, netw)
}
}