1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-06-18 21:45:04 +08:00

Merge pull request #230 from fumiama/master

fix(Mrs4s/go-cqhttp#1267): icmp need su permission
This commit is contained in:
Mrs4s 2022-01-15 17:17:29 +08:00 committed by GitHub
commit c000bf3596
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 75 deletions

View File

@ -67,10 +67,10 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
}()
go func() {
defer wg.Done()
res := utils.RunICMPPingLoop(&net.IPAddr{IP: c.servers[c.currServerIndex].IP}, 10)
res := utils.RunTCPPingLoop(c.servers[c.currServerIndex].String(), 10)
r.ChatServerPacketLoss = res.PacketsLoss
if c.highwaySession.AddrLength() > 0 {
res = utils.RunICMPPingLoop(&net.IPAddr{IP: c.highwaySession.SsoAddr[0].AsNetIP()}, 10)
res = utils.RunTCPPingLoop(c.highwaySession.SsoAddr[0].String(), 10)
r.SrvServerPacketLoss = res.PacketsLoss
}
}()

View File

@ -1,73 +0,0 @@
package utils
import (
"math/rand"
"net"
"time"
"github.com/pkg/errors"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
)
type ICMPPingResult struct {
PacketsSent int
PacketsRecv int
PacketsLoss int
Rtts []int64
}
func RunICMPPingLoop(addr *net.IPAddr, count int) *ICMPPingResult {
if count <= 0 {
return nil
}
r := &ICMPPingResult{
PacketsSent: count,
Rtts: make([]int64, count),
}
for i := 1; i <= count; i++ {
rtt, err := SendICMPRequest(addr, i)
if err != nil {
r.PacketsLoss++
r.Rtts[i-1] = 9999
continue
}
r.PacketsRecv++
r.Rtts[i-1] = rtt
time.Sleep(time.Millisecond * 100)
}
return r
}
func SendICMPRequest(addr *net.IPAddr, seq int) (int64, error) {
data := make([]byte, 32)
rand.Read(data)
body := &icmp.Echo{
ID: 0,
Seq: seq,
Data: data,
}
msg := &icmp.Message{
Type: ipv4.ICMPTypeEcho,
Code: 0,
Body: body,
}
msgBytes, _ := msg.Marshal(nil)
conn, err := net.DialIP("ip4:icmp", nil, addr)
if err != nil {
return 0, errors.Wrap(err, "dial icmp conn error")
}
defer func() { _ = conn.Close() }()
if _, err = conn.Write(msgBytes); err != nil {
return 0, errors.Wrap(err, "write icmp packet error")
}
start := time.Now()
_ = conn.SetReadDeadline(time.Now().Add(time.Second * 2))
buff := make([]byte, 1024)
_, err = conn.Read(buff)
if err != nil {
return 0, errors.Wrap(err, "read icmp conn error")
}
duration := time.Since(start).Milliseconds()
return duration, nil
}

59
utils/tcping.go Normal file
View File

@ -0,0 +1,59 @@
package utils
import (
"net"
"strings"
"time"
)
type ICMPPingResult struct {
PacketsSent int
PacketsLoss int
AvgTimeMill int64
}
// RunTCPPingLoop 使用 tcp 进行 ping
func RunTCPPingLoop(ipport string, count int) (r ICMPPingResult) {
r = ICMPPingResult{
PacketsSent: count,
PacketsLoss: count,
AvgTimeMill: 9999,
}
if count <= 0 {
return
}
durs := make([]int64, 0, count)
for i := 0; i < count; i++ {
d, err := tcping(ipport)
if err == nil {
r.PacketsLoss--
durs = append(durs, d)
}
time.Sleep(time.Millisecond * 100)
}
if len(durs) > 0 {
r.AvgTimeMill = 0
for _, d := range durs {
r.AvgTimeMill += d
}
if len(durs) > 1 {
r.AvgTimeMill /= int64(len(durs))
}
}
return
}
func tcping(ipport string) (int64, error) {
t := time.Now().UnixMilli()
conn, err := net.DialTimeout("tcp", ipport, time.Second*2)
if err != nil {
if strings.Contains(err.Error(), "timeout") {
return 9999, err
}
} else {
_ = conn.Close()
}
return time.Now().UnixMilli() - t, nil
}

12
utils/tcping_test.go Normal file
View File

@ -0,0 +1,12 @@
package utils
import (
"testing"
)
func TestPing(t *testing.T) {
r := RunTCPPingLoop("127.0.0.1:23333", 4)
if r.PacketsLoss == r.PacketsSent {
t.Fatal(r)
}
}