Init
This commit is contained in:
commit
f990e92a9d
29
Makefile
Normal file
29
Makefile
Normal file
|
@ -0,0 +1,29 @@
|
|||
output/arm64/probe:
|
||||
cd probe \
|
||||
&& GOOS=linux GOARCH=arm64 go build -tags netgo -o ../output/arm64/probe
|
||||
|
||||
output/amd64/probe:
|
||||
cd probe \
|
||||
&& GOOS=linux GOARCH=amd64 go build -tags netgo -o ../output/amd64/probe
|
||||
|
||||
output/arm64/probe-server:
|
||||
cd probe-server \
|
||||
&& GOOS=linux GOARCH=arm64 go build -tags netgo -o ../output/arm64/probe-server
|
||||
|
||||
output/amd64/probe-server:
|
||||
cd probe-server \
|
||||
&& GOOS=linux GOARCH=amd64 go build -tags netgo -o ../output/amd64/probe-server
|
||||
|
||||
build-arm64: output/arm64/probe output/arm64/probe-server
|
||||
|
||||
build-amd64: output/amd64/probe output/amd64/probe-server
|
||||
|
||||
build-all: build-arm64 build-amd64
|
||||
|
||||
clean-arm64:
|
||||
rm -f output/arm64/probe*
|
||||
|
||||
clean-amd64:
|
||||
rm -f output/amd64/probe*
|
||||
|
||||
clean-all: clean-arm64 clean-amd64
|
4
go.mod
Normal file
4
go.mod
Normal file
|
@ -0,0 +1,4 @@
|
|||
module git.abbiamoundominio.org/blallo/go-prober
|
||||
|
||||
go 1.15
|
||||
|
12
go.sum
Normal file
12
go.sum
Normal file
|
@ -0,0 +1,12 @@
|
|||
github.com/mozilla/mig v0.0.0-20190913234010-9e7e4f525805 h1:aR0FDMk+x7dz50dqbvd5EPobe2cCHvRbUKGD6HhSXhk=
|
||||
github.com/mozilla/mig v0.0.0-20190913234010-9e7e4f525805/go.mod h1:2c03209qVdj62h4aUMg8KfnbIGC83caKZB8/4F/7YV4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
BIN
output/amd64/probe
Executable file
BIN
output/amd64/probe
Executable file
Binary file not shown.
BIN
output/amd64/probe-server
Executable file
BIN
output/amd64/probe-server
Executable file
Binary file not shown.
BIN
output/arm64/probe
Executable file
BIN
output/arm64/probe
Executable file
Binary file not shown.
BIN
output/arm64/probe-server
Executable file
BIN
output/arm64/probe-server
Executable file
Binary file not shown.
89
probe-server/main.go
Normal file
89
probe-server/main.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"flag"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var PortOutOfRange = errors.New("Port out of allowed range 1-65535")
|
||||
var isDebug bool
|
||||
|
||||
func init() {
|
||||
isDebug = false
|
||||
}
|
||||
|
||||
func debug(v ...interface{}) {
|
||||
if isDebug {
|
||||
msg := make([]interface{}, len(v)+1)
|
||||
msg[0] = "[DEBUG]"
|
||||
for i, el := range v {
|
||||
msg[i+1] = el
|
||||
}
|
||||
log.Println(msg...)
|
||||
}
|
||||
}
|
||||
|
||||
func handleConn(c net.Conn) {
|
||||
defer c.Close()
|
||||
debug("connection established:", c)
|
||||
reader := bufio.NewReader(c)
|
||||
|
||||
for {
|
||||
data, err := reader.ReadString('\n')
|
||||
debug("Data =>", data)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cleanData := strings.TrimSpace(string(data))
|
||||
duration, err := time.ParseDuration(cleanData)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
debug("Duration =>", duration)
|
||||
c.Write([]byte("ACK\n"))
|
||||
time.Sleep(duration)
|
||||
}
|
||||
|
||||
log.Println("connection closed:", c)
|
||||
}
|
||||
|
||||
func parsePort(port int) (string, error) {
|
||||
if port < 1 || port > 65535 {
|
||||
return "", PortOutOfRange
|
||||
}
|
||||
return strconv.Itoa(port), nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var address string
|
||||
var port int
|
||||
flag.StringVar(&address, "addr", "", "The target address or ip")
|
||||
flag.IntVar(&port, "port", 0, "The target port")
|
||||
flag.BoolVar(&isDebug, "debug", false, "Enable debug logging")
|
||||
flag.Parse()
|
||||
|
||||
parsedPort, err := parsePort(port)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
host := net.JoinHostPort(address, parsedPort)
|
||||
server, err := net.Listen("tcp4", host)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
for {
|
||||
c, err := server.Accept()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
go handleConn(c)
|
||||
}
|
||||
}
|
130
probe/main.go
Normal file
130
probe/main.go
Normal file
|
@ -0,0 +1,130 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var PortNotInRange = errors.New("the port number is not in the 0-65535 range")
|
||||
var ServiceNotFound = errors.New("the service is not known")
|
||||
var isDebug bool
|
||||
|
||||
func init() {
|
||||
isDebug = false
|
||||
}
|
||||
|
||||
func debug(v ...interface{}) {
|
||||
if isDebug {
|
||||
msg := make([]interface{}, len(v)+1)
|
||||
msg[0] = "[DEBUG]"
|
||||
for i, el := range v {
|
||||
msg[i+1] = el
|
||||
}
|
||||
log.Println(msg...)
|
||||
}
|
||||
}
|
||||
|
||||
func connect(addr, port string) net.Conn {
|
||||
target := net.JoinHostPort(addr, port)
|
||||
conn, err := net.Dial("tcp", target)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
zero := time.Time{}
|
||||
if err = conn.SetDeadline(zero); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
||||
func validatePort(port int) error {
|
||||
if port < 1 || port > 65535 {
|
||||
return PortNotInRange
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPort(srv string, port int) (string, error) {
|
||||
if port != 0 {
|
||||
return strconv.Itoa(port), nil
|
||||
}
|
||||
return srv, nil
|
||||
}
|
||||
|
||||
func initLogger(logFile string) (*os.File, error) {
|
||||
f, err := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wrt := io.MultiWriter(os.Stdout, f)
|
||||
log.SetOutput(wrt)
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// TODO: planned function that should do some ping measurement and return
|
||||
// the highest value found.
|
||||
func findLatency(address string) (time.Duration, error) {
|
||||
return time.Second, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var address, srv, logFile string
|
||||
var port int
|
||||
var interval, latency, zero time.Duration
|
||||
flag.StringVar(&address, "addr", "", "The target address or ip")
|
||||
flag.IntVar(&port, "port", 0, "The target port")
|
||||
flag.StringVar(&srv, "srv", "", "The target service (will be translated to default port, if -port not provided)")
|
||||
flag.StringVar(&logFile, "log-file", "", "The file path to log to")
|
||||
flag.DurationVar(&interval, "interval", time.Second, "Internal refresh duration (defaults to 1s)")
|
||||
flag.DurationVar(&latency, "latency", zero, "Internal refresh duration (defaults to 1s)")
|
||||
flag.BoolVar(&isDebug, "debug", false, "Enable debug logging")
|
||||
flag.Parse()
|
||||
if port != 0 {
|
||||
validatePort(port)
|
||||
}
|
||||
if logFile == "" {
|
||||
log.Println("Logging only to stdout")
|
||||
} else if f, err := initLogger(logFile); err != nil {
|
||||
log.Fatalf("error opening file: %v", err)
|
||||
f.Close()
|
||||
} else {
|
||||
defer f.Close()
|
||||
}
|
||||
parsedPort, err := getPort(srv, port)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if latency == zero {
|
||||
latency, err = findLatency(address)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
log.Printf("Logging every %v\n", interval)
|
||||
log.Printf("Latency is %v\n", latency)
|
||||
conn := connect(address, parsedPort)
|
||||
intervalStr := fmt.Sprintf("%v\n", interval)
|
||||
for conn != nil {
|
||||
conn.Write([]byte(intervalStr))
|
||||
conn.SetReadDeadline(time.Now().Add(latency))
|
||||
if data, err := bufio.NewReader(conn).ReadString('\n'); err != nil {
|
||||
log.Print(err)
|
||||
conn.Close()
|
||||
conn = nil
|
||||
} else {
|
||||
debug("Data =>", data)
|
||||
conn.SetReadDeadline(time.Now().Add(interval + latency))
|
||||
}
|
||||
time.Sleep(interval)
|
||||
}
|
||||
|
||||
log.Println("Connection closed")
|
||||
}
|
7
units/probe-server.service
Normal file
7
units/probe-server.service
Normal file
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Probe server to allow testing of long-lived connections
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/probe-server -port ${PROBE_PORT}
|
||||
Restart=always
|
8
units/probe.service
Normal file
8
units/probe.service
Normal file
|
@ -0,0 +1,8 @@
|
|||
[Unit]
|
||||
Description=Probe network for disconnections on long-lived connections
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/probe -addr ${PROBE_HOST} -port ${PROBE_PORT} -log-file /var/log/probe/probe.log
|
||||
Restart=always
|
||||
RestartSec=60
|
Loading…
Reference in New Issue
Block a user