175 lines
3.8 KiB
Go
175 lines
3.8 KiB
Go
package tcping
|
||
|
||
import (
|
||
"fmt"
|
||
"github.com/spf13/cobra"
|
||
"os"
|
||
"os/signal"
|
||
"strconv"
|
||
"syscall"
|
||
"time"
|
||
)
|
||
|
||
var (
|
||
counter int
|
||
timeout string
|
||
interval string
|
||
sigs chan os.Signal
|
||
|
||
httpMode bool
|
||
httpHead bool
|
||
httpPost bool
|
||
httpUA string
|
||
|
||
permanent bool
|
||
|
||
dnsServer []string
|
||
)
|
||
|
||
var Cmd = &cobra.Command{
|
||
Use: "tcping",
|
||
Short: "tcp/http ping 工具",
|
||
Long: "使用进行Tcp或Http协议进行ping探测",
|
||
Example: `
|
||
1. dns over tcp
|
||
> tcping google.com
|
||
2. dns over tcp with custom port
|
||
> tcping google.com 443
|
||
3. dns over http
|
||
> tcping -H google.com
|
||
4. dns with URI schema
|
||
> tcping http://hui.lu
|
||
`,
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
sigs = make(chan os.Signal, 1)
|
||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||
if permanent && counter != 4 {
|
||
fmt.Println("不能同时指定-t与-c,请检查您的输入")
|
||
return
|
||
}
|
||
if permanent {
|
||
counter = 0
|
||
}
|
||
if len(args) != 2 && len(args) != 1 {
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
host := args[0]
|
||
|
||
var (
|
||
err error
|
||
port int
|
||
schema string
|
||
)
|
||
if len(args) == 2 {
|
||
port, err = strconv.Atoi(args[1])
|
||
if err != nil {
|
||
fmt.Println("端口应当为Int类型")
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
schema = TCP.String()
|
||
} else {
|
||
var matched bool
|
||
schema, host, port, matched = CheckURI(host)
|
||
if !matched {
|
||
fmt.Println("不是一个合法的URI")
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
}
|
||
var timeoutDuration time.Duration
|
||
if res, err := strconv.Atoi(timeout); err == nil {
|
||
timeoutDuration = time.Duration(res) * time.Millisecond
|
||
} else {
|
||
timeoutDuration, err = time.ParseDuration(timeout)
|
||
if err != nil {
|
||
fmt.Println("parse timeout failed", err)
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
}
|
||
|
||
var intervalDuration time.Duration
|
||
if res, err := strconv.Atoi(interval); err == nil {
|
||
intervalDuration = time.Duration(res) * time.Millisecond
|
||
} else {
|
||
intervalDuration, err = time.ParseDuration(interval)
|
||
if err != nil {
|
||
fmt.Println("parse interval failed", err)
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
}
|
||
var protocol Protocol
|
||
if httpMode {
|
||
protocol = HTTP
|
||
} else {
|
||
protocol, err = NewProtocol(schema)
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
}
|
||
if len(dnsServer) != 0 {
|
||
UseCustomeDNS(dnsServer)
|
||
}
|
||
|
||
parseHost := FormatIP(host)
|
||
target := Target{
|
||
Timeout: timeoutDuration,
|
||
Interval: intervalDuration,
|
||
Host: parseHost,
|
||
Port: port,
|
||
Counter: counter,
|
||
Protocol: protocol,
|
||
}
|
||
var pinger Pinger
|
||
switch protocol {
|
||
case TCP:
|
||
pinger = NewTCPing()
|
||
case HTTP, HTTPS:
|
||
var httpMethod string
|
||
switch {
|
||
case httpHead:
|
||
httpMethod = "HEAD"
|
||
case httpPost:
|
||
httpMethod = "POST"
|
||
default:
|
||
httpMethod = "GET"
|
||
}
|
||
pinger = NewHTTPing(httpMethod)
|
||
default:
|
||
fmt.Printf("schema: %s not support\n", schema)
|
||
cmd.Usage()
|
||
return
|
||
}
|
||
pinger.SetTarget(&target)
|
||
pingerDone := pinger.Start()
|
||
select {
|
||
case <-pingerDone:
|
||
break
|
||
case <-sigs:
|
||
break
|
||
}
|
||
|
||
fmt.Println(pinger.Result())
|
||
},
|
||
}
|
||
|
||
func init() {
|
||
Cmd.Flags().IntVarP(&counter, "counter", "c", 4, "ping的次数")
|
||
Cmd.Flags().BoolVarP(&permanent, "permanent", "t", false, "一直ping下去")
|
||
Cmd.Flags().StringVarP(&timeout, "timeout", "T", "1s", `超时时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
|
||
Cmd.Flags().StringVarP(&interval, "interval", "I", "1s", `ping间隔时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
|
||
|
||
Cmd.Flags().BoolVarP(&httpMode, "http", "H", false, `Use "HTTP" mode. will ignore URI Schema, force to http`)
|
||
Cmd.Flags().BoolVar(&httpHead, "head", false, `使用http head模式`)
|
||
Cmd.Flags().BoolVar(&httpPost, "post", false, `使用http post模式`)
|
||
Cmd.Flags().StringVar(&httpUA, "user-agent", "victorique/tcping", `自定义UA`)
|
||
|
||
Cmd.Flags().StringArrayVarP(&dnsServer, "dns-server", "D", nil, `使用自定义DNS服务器`)
|
||
|
||
}
|