diff --git a/core/server/gen/libcore.pb.go b/core/server/gen/libcore.pb.go index a4779d6..2b57aaa 100644 --- a/core/server/gen/libcore.pb.go +++ b/core/server/gen/libcore.pb.go @@ -914,12 +914,15 @@ func (x *IsPrivilegedResponse) GetHasPrivilege() bool { } type SpeedTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags,proto3" json:"outbound_tags,omitempty"` - TestCurrent bool `protobuf:"varint,3,opt,name=test_current,json=testCurrent,proto3" json:"test_current,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags,proto3" json:"outbound_tags,omitempty"` + TestCurrent bool `protobuf:"varint,3,opt,name=test_current,json=testCurrent,proto3" json:"test_current,omitempty"` + UseDefaultOutbound bool `protobuf:"varint,4,opt,name=use_default_outbound,json=useDefaultOutbound,proto3" json:"use_default_outbound,omitempty"` + TestDownload bool `protobuf:"varint,5,opt,name=test_download,json=testDownload,proto3" json:"test_download,omitempty"` + TestUpload bool `protobuf:"varint,6,opt,name=test_upload,json=testUpload,proto3" json:"test_upload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SpeedTestRequest) Reset() { @@ -973,6 +976,27 @@ func (x *SpeedTestRequest) GetTestCurrent() bool { return false } +func (x *SpeedTestRequest) GetUseDefaultOutbound() bool { + if x != nil { + return x.UseDefaultOutbound + } + return false +} + +func (x *SpeedTestRequest) GetTestDownload() bool { + if x != nil { + return x.TestDownload + } + return false +} + +func (x *SpeedTestRequest) GetTestUpload() bool { + if x != nil { + return x.TestUpload + } + return false +} + type SpeedTestResult struct { state protoimpl.MessageState `protogen:"open.v1"` DlSpeed string `protobuf:"bytes,1,opt,name=dl_speed,json=dlSpeed,proto3" json:"dl_speed,omitempty"` @@ -1259,105 +1283,113 @@ var file_libcore_proto_rawDesc = string([]byte{ 0x14, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x68, 0x61, - 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x22, 0x72, 0x0a, 0x10, 0x53, 0x70, - 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xe2, - 0x01, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x75, 0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x75, 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, - 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, - 0x63, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, - 0x61, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x22, 0x47, 0x0a, 0x11, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x16, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, - 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, - 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x32, 0xfa, 0x07, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x63, - 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x45, 0x78, - 0x69, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, - 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d, - 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, - 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x6c, - 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, - 0x12, 0x10, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x65, 0x73, - 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x38, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x42, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, - 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, - 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, - 0x21, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4e, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x23, 0x2e, - 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, - 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x49, 0x73, 0x50, 0x72, - 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, - 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x70, - 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, - 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, - 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, - 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a, 0x0f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x53, + 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, + 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, + 0x30, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x75, + 0x73, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x74, 0x65, 0x73, + 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xe2, 0x01, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x64, + 0x6c, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x6c, 0x5f, 0x73, 0x70, 0x65, + 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x6c, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x47, 0x0a, 0x11, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, + 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x32, 0xfa, 0x07, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x45, 0x78, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, + 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, + 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, + 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, + 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x6c, 0x69, 0x62, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, + 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, + 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x38, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, + 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x42, 0x0a, 0x0f, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x11, + 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, + 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x47, 0x65, + 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, + 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, + 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, + 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x4e, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, + 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, + 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x12, + 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, + 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, + 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x49, + 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, + 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6c, + 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, + 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a, + 0x0f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( diff --git a/core/server/gen/libcore.proto b/core/server/gen/libcore.proto index a5c458f..9949c61 100644 --- a/core/server/gen/libcore.proto +++ b/core/server/gen/libcore.proto @@ -115,6 +115,9 @@ message SpeedTestRequest { string config = 1; repeated string outbound_tags = 2; bool test_current = 3; + bool use_default_outbound = 4; + bool test_download = 5; + bool test_upload = 6; } message SpeedTestResult { diff --git a/core/server/go.mod b/core/server/go.mod index c620f15..d9cead3 100644 --- a/core/server/go.mod +++ b/core/server/go.mod @@ -5,6 +5,7 @@ go 1.23.0 toolchain go1.24.0 require ( + github.com/Mahdi-zarei/speedtest-go v1.7.12 github.com/dustin/go-humanize v1.0.1 github.com/gofrs/uuid/v5 v5.3.2 github.com/oschwald/maxminddb-golang v1.13.1 @@ -23,7 +24,6 @@ replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0 replace github.com/sagernet/sing-dns => github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492 require ( - github.com/Mahdi-zarei/speedtest-go v1.7.11 // indirect github.com/ajg/form v1.5.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/caddyserver/certmagic v0.20.0 // indirect diff --git a/core/server/go.sum b/core/server/go.sum index 5d21ddb..f1b762d 100644 --- a/core/server/go.sum +++ b/core/server/go.sum @@ -2,8 +2,8 @@ github.com/Mahdi-zarei/sing-box v1.3.5-0.20250419091424-318eff0efb34 h1:xhAgBfvZ github.com/Mahdi-zarei/sing-box v1.3.5-0.20250419091424-318eff0efb34/go.mod h1:wMfYe7SB/9L11IuO7r0A5Rh6eoxGsyjoErxeYwqLgXU= github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492 h1:fLReuPi1fM99oFRERDU96JzEY1YpLh8PmDGEcfnexCY= github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20250419091211-cee3ab2d4492/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8= -github.com/Mahdi-zarei/speedtest-go v1.7.11 h1:K/c7qBlJNAYGv6MujDaIKvtb4AH+yPRdssZ1NJMGPFU= -github.com/Mahdi-zarei/speedtest-go v1.7.11/go.mod h1:b1H+UBFUnLKH1YquN2xao8d1hokcnDFFhEKDARTzddM= +github.com/Mahdi-zarei/speedtest-go v1.7.12 h1:KktFSpobkhIgrOd25e8IpVzVq2enpCDzQQPVtGxWZV4= +github.com/Mahdi-zarei/speedtest-go v1.7.12/go.mod h1:b1H+UBFUnLKH1YquN2xao8d1hokcnDFFhEKDARTzddM= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= diff --git a/core/server/server.go b/core/server/server.go index 00cefc6..b82d3e6 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -311,6 +311,9 @@ func (s *server) IsPrivileged(ctx context.Context, _ *gen.EmptyReq) (*gen.IsPriv } func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.SpeedTestResponse, error) { + if !in.TestDownload && !in.TestUpload { + return nil, errors.New("cannot run empty test") + } var testInstance *boxbox.Box var cancel context.CancelFunc outboundTags := in.OutboundTags @@ -323,8 +326,6 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen. }}}, nil } testInstance = boxInstance - outbound := testInstance.Outbound().Default() - outboundTags = []string{outbound.Tag()} } else { testInstance, cancel, err = boxmain.Create([]byte(in.Config)) if err != nil { @@ -334,7 +335,12 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen. defer testInstance.Close() } - results := BatchSpeedTest(testCtx, testInstance, outboundTags) + if in.UseDefaultOutbound || in.TestCurrent { + outbound := testInstance.Outbound().Default() + outboundTags = []string{outbound.Tag()} + } + + results := BatchSpeedTest(testCtx, testInstance, outboundTags, in.TestDownload, in.TestUpload) res := make([]*gen.SpeedTestResult, 0) for _, data := range results { diff --git a/core/server/test_utils.go b/core/server/test_utils.go index eb3b0f2..149fc1b 100644 --- a/core/server/test_utils.go +++ b/core/server/test_utils.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/Mahdi-zarei/speedtest-go/speedtest" "github.com/sagernet/sing-box/adapter" + E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/metadata" "github.com/sagernet/sing/service" "nekobox_core/internal/boxbox" @@ -137,15 +138,20 @@ func urlTest(ctx context.Context, client *http.Client, url string) (time.Duratio func getNetDialer(dialer func(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error)) func(ctx context.Context, network string, address string) (net.Conn, error) { return func(ctx context.Context, network string, address string) (net.Conn, error) { - return dialer(ctx, network, metadata.Socksaddr{Addr: metadata.ParseAddr(address)}) + return dialer(ctx, network, metadata.ParseSocksaddr(address)) } } -func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string) []*SpeedTestResult { +func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string, testDl, testUl bool) []*SpeedTestResult { outbounds := service.FromContext[adapter.OutboundManager](i.Context()) results := make([]*SpeedTestResult, 0) for _, tag := range outboundTags { + select { + case <-ctx.Done(): + break + default: + } outbound, exists := outbounds.Outbound(tag) if !exists { panic("no outbound with tag " + tag + " found") @@ -154,19 +160,23 @@ func BatchSpeedTest(ctx context.Context, i *boxbox.Box, outboundTags []string) [ res.Tag = tag results = append(results, res) - insCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - err := speedTestWithDialer(insCtx, getNetDialer(outbound.DialContext), res) - cancel() + err := speedTestWithDialer(ctx, getNetDialer(outbound.DialContext), res, testDl, testUl) if err != nil { res.Error = err fmt.Println("Failed to speedtest with err:", err) } + if !testDl { + res.DlSpeed = "" + } + if !testUl { + res.UlSpeed = "" + } } return results } -func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, network string, address string) (net.Conn, error), res *SpeedTestResult) error { +func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, network string, address string) (net.Conn, error), res *SpeedTestResult, testDl, testUl bool) error { clt := speedtest.New(speedtest.WithUserConfig(&speedtest.UserConfig{ DialContextFunc: dialer, PingMode: speedtest.HTTP, @@ -194,15 +204,19 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n go func() { defer func() { close(done) }() - err = srv[0].DownloadTestContext(ctx) - if err != nil { - res.Error = err - return + if testDl { + err = srv[0].DownloadTestContext(ctx) + if err != nil { + res.Error = err + return + } } - err = srv[0].UploadTestContext(ctx) - if err != nil { - res.Error = err - return + if testUl { + err = srv[0].UploadTestContext(ctx) + if err != nil { + res.Error = err + return + } } }() @@ -218,7 +232,7 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n SpTQuerier.storeResult(res) return nil case <-ctx.Done(): - return ctx.Err() + return E.New("test cancelled") case <-ticker.C: res.DlSpeed = speedtest.ByteRate(srv[0].Context.GetEWMADownloadRate()).String() res.UlSpeed = speedtest.ByteRate(srv[0].Context.GetEWMAUploadRate()).String() diff --git a/include/dataStore/ProxyEntity.hpp b/include/dataStore/ProxyEntity.hpp index fbf7063..c58df0a 100644 --- a/include/dataStore/ProxyEntity.hpp +++ b/include/dataStore/ProxyEntity.hpp @@ -34,6 +34,8 @@ namespace NekoGui { int id = -1; int gid = 0; int latency = 0; + QString dl_speed; + QString ul_speed; std::shared_ptr bean; std::shared_ptr traffic_data = std::make_shared(""); @@ -41,7 +43,7 @@ namespace NekoGui { ProxyEntity(NekoGui_fmt::AbstractBean *bean, const QString &type_); - [[nodiscard]] QString DisplayLatency() const; + [[nodiscard]] QString DisplayTestResult() const; [[nodiscard]] QColor DisplayLatencyColor() const; diff --git a/include/global/Const.hpp b/include/global/Const.hpp index 3034b94..309cb04 100644 --- a/include/global/Const.hpp +++ b/include/global/Const.hpp @@ -33,4 +33,14 @@ namespace GeoAssets { inline QStringList GeoIPURLs = {"https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geoip.db"}; inline QStringList GeoSiteURLs = {"https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geosite.db"}; } + + namespace TestConfig + { + enum SpeedTestMode + { + FULL, + DL, + UL, + }; + } } // namespace NekoGui diff --git a/include/global/NekoGui_DataStore.hpp b/include/global/NekoGui_DataStore.hpp index d048096..a5c0f45 100644 --- a/include/global/NekoGui_DataStore.hpp +++ b/include/global/NekoGui_DataStore.hpp @@ -1,5 +1,7 @@ // DO NOT INCLUDE THIS +#include "Const.hpp" + namespace NekoGui { class Routing : public JsonStore { @@ -80,6 +82,7 @@ namespace NekoGui { QString splitter_state = ""; bool enable_stats = true; QString stats_tab = ""; // either connection or log + int speed_test_mode = TestConfig::FULL; // Subscription QString user_agent = ""; // set at main.cpp diff --git a/include/ui/mainwindow.h b/include/ui/mainwindow.h index 924cf79..4d904e7 100644 --- a/include/ui/mainwindow.h +++ b/include/ui/mainwindow.h @@ -219,14 +219,18 @@ private: static void setup_grpc(); - void speedtest_current_group(const QList>& profiles); + void urltest_current_group(const QList>& profiles); - void stopSpeedTests(); + void stopTests(); - void RunSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID = -1); + void runURLTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID = -1); void url_test_current(); + void speedtest_current_group(const QList>& profiles); + + void runSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID = -1); + static void stop_core_daemon(); bool set_system_dns(bool set, bool save_set = true); diff --git a/include/ui/mainwindow.ui b/include/ui/mainwindow.ui index a9ba096..18fe6d5 100644 --- a/include/ui/mainwindow.ui +++ b/include/ui/mainwindow.ui @@ -602,6 +602,8 @@ + + @@ -614,6 +616,7 @@ + @@ -1006,6 +1009,21 @@ Open Manager + + + Speedtest Current + + + + + Speedtest Selected + + + + + Speedtest Group + + diff --git a/include/ui/setting/dialog_basic_settings.ui b/include/ui/setting/dialog_basic_settings.ui index e770612..668fdb0 100644 --- a/include/ui/setting/dialog_basic_settings.ui +++ b/include/ui/setting/dialog_basic_settings.ui @@ -179,6 +179,44 @@ + + + + QFrame::Shape::StyledPanel + + + QFrame::Shadow::Raised + + + + + + Speedtest mode + + + + + + + + Download + Upload + + + + + Only Download + + + + + Only Upload + + + + + + + diff --git a/src/dataStore/Database.cpp b/src/dataStore/Database.cpp index 3386e98..11661fd 100644 --- a/src/dataStore/Database.cpp +++ b/src/dataStore/Database.cpp @@ -249,6 +249,8 @@ namespace NekoGui { _add(new configItem("id", &id, itemType::integer)); _add(new configItem("gid", &gid, itemType::integer)); _add(new configItem("yc", &latency, itemType::integer)); + _add(new configItem("dl", &dl_speed, itemType::string)); + _add(new configItem("ul", &ul_speed, itemType::string)); _add(new configItem("report", &full_test_report, itemType::string)); // 可以不关联 bean,只加载 ProxyEntity 的信息 @@ -260,14 +262,16 @@ namespace NekoGui { } }; - QString ProxyEntity::DisplayLatency() const { + QString ProxyEntity::DisplayTestResult() const { + QString result; if (latency < 0) { - return QObject::tr("Unavailable"); + result = "Unavailable"; } else if (latency > 0) { - return UNICODE_LRO + QString("%1 ms").arg(latency); - } else { - return ""; + result = UNICODE_LRO + QString("%1 ms").arg(latency); } + if (!dl_speed.isEmpty()) result += " ↓" + dl_speed; + if (!ul_speed.isEmpty()) result += " ↑" + ul_speed; + return result; } QColor ProxyEntity::DisplayLatencyColor() const { diff --git a/src/global/NekoGui.cpp b/src/global/NekoGui.cpp index 88416f1..7943d7a 100644 --- a/src/global/NekoGui.cpp +++ b/src/global/NekoGui.cpp @@ -308,6 +308,7 @@ namespace NekoGui { _add(new configItem("proxy_scheme", &proxy_scheme, itemType::string)); _add(new configItem("disable_privilege_req", &disable_privilege_req, itemType::boolean)); _add(new configItem("enable_tun_routing", &enable_tun_routing, itemType::boolean)); + _add(new configItem("speed_test_mode", &speed_test_mode, itemType::integer)); } void DataStore::UpdateStartedId(int id) { diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 2369fa6..03f8ace 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -421,6 +421,24 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi #endif connect(ui->menu_server, &QMenu::aboutToShow, this, [=](){ + if (running) + { + ui->actionSpeedtest_Current->setEnabled(true); + } else + { + ui->actionSpeedtest_Current->setEnabled(false); + } + if (auto selected = get_now_selected_list(); selected.empty()) + { + ui->actionSpeedtest_Selected->setEnabled(false); + ui->actionUrl_Test_Selected->setEnabled(false); + ui->menu_resolve_selected->setEnabled(false); + } else + { + ui->actionSpeedtest_Selected->setEnabled(true); + ui->actionUrl_Test_Selected->setEnabled(true); + ui->menu_resolve_selected->setEnabled(true); + } if (!speedtestRunning.tryLock()) { ui->menu_server->addAction(ui->menu_stop_testing); } else { @@ -452,12 +470,27 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi } }); connect(ui->actionUrl_Test_Selected, &QAction::triggered, this, [=]() { - speedtest_current_group(get_now_selected_list()); + urltest_current_group(get_now_selected_list()); }); connect(ui->actionUrl_Test_Group, &QAction::triggered, this, [=]() { + urltest_current_group(NekoGui::profileManager->CurrentGroup()->Profiles()); + }); + connect(ui->actionSpeedtest_Current, &QAction::triggered, this, [=]() + { + if (running != nullptr) + { + speedtest_current_group({running}); + } + }); + connect(ui->actionSpeedtest_Selected, &QAction::triggered, this, [=]() + { + speedtest_current_group(get_now_selected_list()); + }); + connect(ui->actionSpeedtest_Group, &QAction::triggered, this, [=]() + { speedtest_current_group(NekoGui::profileManager->CurrentGroup()->Profiles()); }); - connect(ui->menu_stop_testing, &QAction::triggered, this, [=]() { stopSpeedTests(); }); + connect(ui->menu_stop_testing, &QAction::triggered, this, [=]() { stopTests(); }); // auto set_selected_or_group = [=](int mode) { // 0=group 1=select 2=unknown(menu is hide) @@ -561,7 +594,6 @@ void MainWindow::show_group(int gid) { ui->tabWidget->widget(groupId2TabIndex(gid))->layout()->addWidget(ui->proxyListTable); - // 列宽是否可调 if (group->manually_column_width) { for (int i = 0; i <= 4; i++) { ui->proxyListTable->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Interactive); @@ -1376,7 +1408,7 @@ void MainWindow::refresh_table_item(const int row, const std::shared_ptrfull_test_report.isEmpty()) { auto color = profile->DisplayLatencyColor(); if (color.isValid()) f->setForeground(color); - f->setText(profile->DisplayLatency()); + f->setText(profile->DisplayTestResult()); } else { f->setText(profile->full_test_report); } @@ -1726,6 +1758,8 @@ void MainWindow::on_menu_scan_qr_triggered() { void MainWindow::on_menu_clear_test_result_triggered() { for (const auto &profile: get_selected_or_group()) { profile->latency = 0; + profile->dl_speed.clear(); + profile->ul_speed.clear(); profile->full_test_report = ""; profile->Save(); } @@ -2056,6 +2090,7 @@ void MainWindow::on_tabWidget_customContextMenuRequested(const QPoint &p) { if (NekoGui::profileManager->groups.size() > 1) menu->addAction(deleteAction); if (!group->Profiles().empty()) { menu->addAction(ui->actionUrl_Test_Group); + menu->addAction(ui->actionSpeedtest_Group); menu->addAction(ui->menu_resolve_domain); menu->addAction(ui->menu_clear_test_result); menu->addAction(ui->menu_delete_repeat); diff --git a/src/ui/mainwindow_grpc.cpp b/src/ui/mainwindow_grpc.cpp index 88507e2..d4cb1e3 100644 --- a/src/ui/mainwindow_grpc.cpp +++ b/src/ui/mainwindow_grpc.cpp @@ -29,7 +29,7 @@ void MainWindow::setup_grpc() { runOnNewThread([=] {NekoGui_traffic::connection_lister->Loop(); }); } -void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID) { +void MainWindow::runURLTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID) { if (stopSpeedtest.load()) { MW_show_log(tr("Profile test aborted")); return; @@ -78,12 +78,12 @@ void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStr } } -void MainWindow::speedtest_current_group(const QList>& profiles) { +void MainWindow::urltest_current_group(const QList>& profiles) { if (profiles.isEmpty()) { return; } if (!speedtestRunning.tryLock()) { - MessageBoxWarning(software_name, tr("The last speed test did not exit completely, please wait. If it persists, please restart the program.")); + MessageBoxWarning(software_name, tr("The last url test did not exit completely, please wait. If it persists, please restart the program.")); return; } @@ -101,7 +101,7 @@ void MainWindow::speedtest_current_group(const QListfullConfigs.keys()) { auto configStr = buildObject->fullConfigs[entID]; auto func = [this, &counter, testCount, configStr, entID]() { - MainWindow::RunSpeedTest(configStr, true, {}, {}, entID); + MainWindow::runURLTest(configStr, true, {}, {}, entID); counter++; if (counter.load() == testCount) { speedtestRunning.unlock(); @@ -112,7 +112,7 @@ void MainWindow::speedtest_current_group(const QListoutboundTags.empty()) { auto func = [this, &buildObject, &counter, testCount]() { - MainWindow::RunSpeedTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID); + MainWindow::runURLTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID); counter++; if (counter.load() == testCount) { speedtestRunning.unlock(); @@ -126,12 +126,12 @@ void MainWindow::speedtest_current_group(const QListStopTests(&ok); @@ -170,6 +170,96 @@ void MainWindow::url_test_current() { }); } +void MainWindow::speedtest_current_group(const QList>& profiles) +{ + if (profiles.isEmpty()) { + return; + } + if (!speedtestRunning.tryLock()) { + MessageBoxWarning(software_name, tr("The last speed test did not exit completely, please wait. If it persists, please restart the program.")); + return; + } + + runOnNewThread([this, profiles]() { + auto buildObject = NekoGui::BuildTestConfig(profiles); + if (!buildObject->error.isEmpty()) { + MW_show_log(tr("Failed to build test config: ") + buildObject->error); + speedtestRunning.unlock(); + return; + } + + stopSpeedtest.store(false); + for (const auto &entID: buildObject->fullConfigs.keys()) { + auto configStr = buildObject->fullConfigs[entID]; + runSpeedTest(configStr, true, {}, {}, entID); + } + + if (!buildObject->outboundTags.empty()) { + runSpeedTest(QJsonObject2QString(buildObject->coreConfig, false), false, buildObject->outboundTags, buildObject->tag2entID); + } + + speedtestRunning.unlock(); + runOnUiThread([=]{ + refresh_proxy_list(); + MW_show_log(tr("Speedtest finished!")); + }); + }); +} + +void MainWindow::runSpeedTest(const QString& config, bool useDefault, const QStringList& outboundTags, const QMap& tag2entID, int entID) +{ + if (stopSpeedtest.load()) { + MW_show_log(tr("Profile speed test aborted")); + return; + } + + libcore::SpeedTestRequest req; + auto speedtestConf = NekoGui::dataStore->speed_test_mode; + for (const auto &item: outboundTags) { + req.add_outbound_tags(item.toStdString()); + } + req.set_config(config.toStdString()); + req.set_use_default_outbound(useDefault); + req.set_test_download(speedtestConf == NekoGui::TestConfig::FULL || speedtestConf == NekoGui::TestConfig::DL); + req.set_test_upload(speedtestConf == NekoGui::TestConfig::FULL || speedtestConf == NekoGui::TestConfig::UL); + + bool rpcOK; + auto result = defaultClient->SpeedTest(&rpcOK, req); + // + if (!rpcOK) return; + + for (const auto &res: result.results()) { + if (!tag2entID.empty()) { + entID = tag2entID.count(QString(res.outbound_tag().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag().c_str())]; + } + if (entID == -1) { + MW_show_log(tr("Something is very wrong, the subject ent cannot be found!")); + continue; + } + + auto ent = NekoGui::profileManager->GetProfile(entID); + if (ent == nullptr) { + MW_show_log(tr("Profile manager data is corrupted, try again.")); + continue; + } + + if (res.error().empty()) { + ent->dl_speed = res.dl_speed().c_str(); + ent->ul_speed = res.ul_speed().c_str(); + if (ent->latency <= 0 && res.latency() > 0) ent->latency = res.latency(); + } else { + if (QString(res.error().c_str()).contains("test aborted") || + QString(res.error().c_str()).contains("context canceled")) ent->dl_speed = "", ent->ul_speed = ""; + else { + ent->dl_speed = "N/A"; + ent->ul_speed = "N/A"; + MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error().c_str())); + } + } + ent->Save(); + } +} + void MainWindow::stop_core_daemon() { NekoGui_rpc::defaultClient->Exit(); } diff --git a/src/ui/profile/ProxyItem.cpp b/src/ui/profile/ProxyItem.cpp index 8af6825..9e0ddc9 100644 --- a/src/ui/profile/ProxyItem.cpp +++ b/src/ui/profile/ProxyItem.cpp @@ -23,7 +23,7 @@ void ProxyItem::refresh_data() { ui->name->setText(ent->bean->DisplayName()); ui->address->setText(ent->bean->DisplayAddress()); ui->traffic->setText(ent->traffic_data->DisplayTraffic()); - ui->test_result->setText(ent->DisplayLatency()); + ui->test_result->setText(ent->DisplayTestResult()); runOnUiThread( [=] { diff --git a/src/ui/setting/dialog_basic_settings.cpp b/src/ui/setting/dialog_basic_settings.cpp index f96d5ae..80ac26c 100644 --- a/src/ui/setting/dialog_basic_settings.cpp +++ b/src/ui/setting/dialog_basic_settings.cpp @@ -33,6 +33,7 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) D_LOAD_INT(inbound_socks_port) D_LOAD_INT(test_concurrent) D_LOAD_STRING(test_latency_url) + ui->speedtest_mode->setCurrentIndex(NekoGui::dataStore->speed_test_mode); connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] { C_EDIT_JSON_ALLOW_EMPTY(custom_inbound) @@ -167,6 +168,7 @@ void DialogBasicSettings::accept() { D_SAVE_INT(test_concurrent) D_SAVE_STRING(test_latency_url) NekoGui::dataStore->proxy_scheme = ui->proxy_scheme->currentText().toLower(); + NekoGui::dataStore->speed_test_mode = ui->speedtest_mode->currentIndex(); // Style