Files
nekoray/go/grpc_server/fulltest.go
2023-05-30 13:21:24 +09:00

138 lines
2.9 KiB
Go

package grpc_server
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"grpc_server/gen"
"io"
"log"
"net"
"strings"
"time"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/speedtest"
)
func DoFullTest(ctx context.Context, in *gen.TestReq, instance interface{}) (out *gen.TestResp, _ error) {
out = &gen.TestResp{}
httpClient := neko_common.CreateProxyHttpClient(instance)
// Latency
var latency string
if in.FullLatency {
t, _ := speedtest.UrlTest(httpClient, in.Url, in.Timeout)
out.Ms = t
if t > 0 {
latency = fmt.Sprint(t, "ms")
} else {
latency = "Error"
}
}
// UDP Latency
var udpLatency string
if in.FullUdpLatency {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
result := make(chan string)
go func() {
var startTime = time.Now()
pc, err := neko_common.DialContext(ctx, instance, "udp", "8.8.8.8:53")
if err == nil {
defer pc.Close()
dnsPacket, _ := hex.DecodeString("0000010000010000000000000377777706676f6f676c6503636f6d0000010001")
_, err = pc.Write(dnsPacket)
if err == nil {
var buf [1400]byte
_, err = pc.Read(buf[:])
}
}
if err == nil {
var endTime = time.Now()
result <- fmt.Sprint(endTime.Sub(startTime).Abs().Milliseconds(), "ms")
} else {
log.Println("UDP Latency test error:", err)
result <- "Error"
}
close(result)
}()
select {
case <-ctx.Done():
udpLatency = "Timeout"
case r := <-result:
udpLatency = r
}
cancel()
}
// 入口 IP
var in_ip string
if in.FullInOut {
_in_ip, err := net.ResolveIPAddr("ip", in.InAddress)
if err == nil {
in_ip = _in_ip.String()
} else {
in_ip = err.Error()
}
}
// 出口 IP
var out_ip string
if in.FullInOut {
resp, err := httpClient.Get("https://httpbin.org/get")
if err == nil {
v := make(map[string]interface{})
json.NewDecoder(resp.Body).Decode(&v)
if a, ok := v["origin"]; ok {
if s, ok := a.(string); ok {
out_ip = s
}
}
resp.Body.Close()
} else {
out_ip = "Error"
}
}
// 下载
var speed string
if in.FullSpeed {
resp, err := httpClient.Get("http://cachefly.cachefly.net/10mb.test")
if err == nil {
time_start := time.Now()
n, _ := io.Copy(io.Discard, resp.Body)
time_end := time.Now()
speed = fmt.Sprintf("%.2fMiB/s", (float64(n)/time_end.Sub(time_start).Seconds())/1048576)
resp.Body.Close()
} else {
speed = "Error"
}
}
fr := make([]string, 0)
if latency != "" {
fr = append(fr, fmt.Sprintf("Latency: %s", latency))
}
if udpLatency != "" {
fr = append(fr, fmt.Sprintf("UDPLatency: %s", udpLatency))
}
if speed != "" {
fr = append(fr, fmt.Sprintf("Speed: %s", speed))
}
if in_ip != "" {
fr = append(fr, fmt.Sprintf("In: %s", in_ip))
}
if out_ip != "" {
fr = append(fr, fmt.Sprintf("Out: %s", out_ip))
}
out.FullReport = strings.Join(fr, " / ")
return
}