Skip to content

Commit

Permalink
feat: add TcpingCommand and flags for IPv4, IPv6, count, and timeout
Browse files Browse the repository at this point in the history
- Remove the import of `github.com/ergoapi/util/zos`
- Add the `debug/tcping.go` file
- Add the `TcpingCommand` function to `debug.go`
- Add flags for ipv4, ipv6, count, and timeout to the `TcpingCommand` function
- Add a check for the `zos.IsLinux()` condition before adding the `debug.TcpingCommand` command in `newCmdDebug` function

Signed-off-by: ysicing <i@ysicing.me>
  • Loading branch information
ysicing committed Apr 26, 2024
1 parent 9a29626 commit 17e853b
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 14 deletions.
7 changes: 3 additions & 4 deletions cmd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"os"

"github.com/ergoapi/util/zos"
"github.com/spf13/cobra"
"github.com/ysicing/tiga/cmd/debug"
"github.com/ysicing/tiga/cmd/xray"
Expand All @@ -29,9 +28,9 @@ func newCmdDebug(f factory.Factory) *cobra.Command {
debugCmd.AddCommand(debug.GOpsCommand(f))
debugCmd.AddCommand(debug.NetCheckCommand(f))
debugCmd.AddCommand(debug.IPMMDBCommand(f))
if zos.IsLinux() {
debugCmd.AddCommand(debug.ChinaRouteCommand(f))
}
debugCmd.AddCommand(debug.TcpingCommand(f))
debugCmd.AddCommand(debug.ChinaRouteCommand(f))

// Deprecated commands
xray := xray.NewCmdXray(f)
xray.Deprecated = "please use xray"
Expand Down
158 changes: 158 additions & 0 deletions cmd/debug/tcping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright (c) 2023 ysicing(ysicing.me, ysicing@12306.work) All rights reserved.
// Use of this source code is covered by the following dual licenses:
// (1) Y PUBLIC LICENSE 1.0 (YPL 1.0)
// (2) Affero General Public License 3.0 (AGPL 3.0)
// License that can be found in the LICENSE file.

package debug

import (
"fmt"
"net"
"os"
"os/signal"
"strings"
"syscall"
"time"

"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
"github.com/ysicing/tiga/pkg/factory"
"k8s.io/kubectl/pkg/util/templates"
)

var (
tcpingExample = templates.Examples(`
# simple tcping
tiga debug tcping [-4] [-6] [-n count] [-t timeout] address port
`)
)

func TcpingCommand(f factory.Factory) *cobra.Command {
var ipv4, ipv6 bool
var count, timeout int
var stopPing chan bool
cmd := &cobra.Command{
Use: "tcping",
Short: "tcping",
Example: tcpingExample,
PreRunE: func(cmd *cobra.Command, args []string) error {
if ipv4 && ipv6 {
return errors.New("ipv4 and ipv6 can't be used together")
}
if len(args) < 2 {
return errors.New("address and port is required")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
var err error
address := args[0]
port := args[1]
if ipv4 || (!ipv6 && isIPv4(address)) {
address, err = resolveAddress(address, "ipv4")
} else if ipv6 || isIPv6(address) {
address, err = resolveAddress(address, "ipv6")
} else {
// Default to IPv4 if no -4 or -6 flags specified and address is not explicitly IPv6
address, err = resolveAddress(address, "ipv4")
}
if err != nil {
return err
}
f.GetLog().Infof("start ping %s:%s...", address, port)
stopPing = make(chan bool, 1)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
var sentCount int
var respondedCount int
var minTime, maxTime, totalResponseTime int64
go func() {
for i := 0; count == 0 || i < count; i++ {
select {
case <-stopPing:
return
default:
start := time.Now()
conn, err := net.DialTimeout("tcp", address+":"+port, time.Duration(timeout)*time.Second)
elapsed := time.Since(start).Milliseconds()

sentCount++
if err != nil {
f.GetLog().Warnf("Failed to connect to %s:%s: %v", address, port, err)
} else {
conn.Close()
respondedCount++
if respondedCount == 1 || elapsed < minTime {
minTime = elapsed
}
if elapsed > maxTime {
maxTime = elapsed
}
totalResponseTime += elapsed
fmt.Printf("tcping %s:%s in %dms\n", address, port, elapsed)
}

if count != 0 && i == count-1 {
break
}

time.Sleep(time.Duration(timeout) * time.Second)
}
}
stopPing <- true
}()

select {
case <-interrupt:
f.GetLog().Warn("ping interrupted.")
stopPing <- true
case <-stopPing:
f.GetLog().Done("ping stopped.")
}
printTcpingStatistics(sentCount, respondedCount, minTime, maxTime, totalResponseTime)
return nil
},
}
cmd.Flags().BoolVarP(&ipv4, "ipv4", "4", false, "ipv4")
cmd.Flags().BoolVarP(&ipv6, "ipv6", "6", false, "ipv6")
cmd.Flags().IntVarP(&count, "count", "c", 3, "number of pings")
cmd.Flags().IntVarP(&timeout, "timeout", "t", 3, "time interval between pings in seconds ")
return cmd
}

func isIPv4(address string) bool {
return strings.Count(address, ":") == 0
}

// resolveAddress resolves the address to the specified network type
func isIPv6(address string) bool {
return strings.Count(address, ":") >= 2
}

func resolveAddress(address, version string) (string, error) {
ipList, err := net.LookupIP(address)
if err != nil {
return "", errors.Errorf("failed to resolve %s: %v", address, err)
}

for _, ip := range ipList {
if version == "ipv4" && ip.To4() != nil {
return ip.String(), nil
} else if version == "ipv6" && ip.To16() != nil && ip.To4() == nil {
return "[" + ip.String() + "]", nil
}
}
return "", errors.Errorf("no %s addresses found for %s", version, address)
}

func printTcpingStatistics(sentCount, respondedCount int, minTime, maxTime, totalResponseTime int64) {
fmt.Println("")
fmt.Println("--- Tcping Statistics ---")
fmt.Printf("%d tcp ping sent, %d tcp ping responsed, %.2f%% loss\n", sentCount, respondedCount, float64(sentCount-respondedCount)/float64(sentCount)*100)
if respondedCount > 0 {
fmt.Printf("min/avg/max = %dms/%dms/%dms\n", minTime, totalResponseTime/int64(respondedCount), maxTime)
} else {
fmt.Println("No responses received.")
}
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ require (
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
Expand Down Expand Up @@ -148,8 +148,8 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230420174744-55c8b9515a01 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xtls/reality v0.0.0-20231112171332-de1173cf2b19 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9
github.com/loft-sh/utils v0.0.21 h1:GSmg/PL90rfR3RzVlNIu1kK5xWWECiSsxxPHwzG5rgo=
github.com/loft-sh/utils v0.0.21/go.mod h1:0lw0bzifz03np3AJvwVLCTAfWK8AE2dNwfEAq/YxoyY=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk=
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
Expand Down Expand Up @@ -340,11 +340,11 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4=
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
Expand Down
2 changes: 1 addition & 1 deletion hack/licenses/licenses.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2023 ysicing(ysicing.me, ysicing@12306.work) All rights reserved.
Copyright (c) 2024 ysicing(ysicing.me, ysicing@12306.work) All rights reserved.
Use of this source code is covered by the following dual licenses:
(1) Y PUBLIC LICENSE 1.0 (YPL 1.0)
(2) Affero General Public License 3.0 (AGPL 3.0)
Expand Down

0 comments on commit 17e853b

Please sign in to comment.