add api option

This commit is contained in:
Page Fault
2020-05-28 07:58:11 +00:00
parent ab91d67fef
commit 87041a73f7
15 changed files with 414 additions and 237 deletions
+178
View File
@@ -0,0 +1,178 @@
package control
import (
"context"
"encoding/json"
"flag"
"fmt"
"io"
"github.com/p4gefau1t/trojan-go/api/service"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/log"
"google.golang.org/grpc"
)
type apiOption struct {
address *string
key *string
hash *string
cert *string
cmd *string
password *string
add *bool
delete *bool
modify *bool
list *bool
uploadSpeedLimit *int
downloadSpeedLimit *int
iplimit *int
ctx context.Context
}
func (apiOption) Name() string {
return "api"
}
func (o *apiOption) listUsers(apiClient service.TrojanServerServiceClient) error {
stream, err := apiClient.ListUsers(o.ctx, &service.ListUsersRequest{})
if err != nil {
return err
}
defer stream.CloseSend()
for {
resp, err := stream.Recv()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
data, err := json.Marshal(resp)
common.Must(err)
fmt.Print(string(data))
}
}
func (o *apiOption) getUsers(apiClient service.TrojanServerServiceClient) error {
stream, err := apiClient.GetUsers(o.ctx)
if err != nil {
return err
}
defer stream.CloseSend()
err = stream.Send(&service.GetUsersRequest{
User: &service.User{
Password: *o.password,
Hash: *o.hash,
},
})
if err != nil {
return err
}
resp, err := stream.Recv()
if err != nil {
return err
}
data, err := json.Marshal(resp)
common.Must(err)
fmt.Print(string(data))
return nil
}
func (o *apiOption) setUsers(apiClient service.TrojanServerServiceClient) error {
stream, err := apiClient.SetUsers(o.ctx)
if err != nil {
return err
}
defer stream.CloseSend()
req := &service.SetUsersRequest{
User: &service.User{
Password: *o.password,
Hash: *o.hash,
},
IpLimit: int32(*o.iplimit),
SpeedLimit: &service.Speed{
UploadSpeed: uint64(*o.uploadSpeedLimit),
DownloadSpeed: uint64(*o.downloadSpeedLimit),
},
}
if *o.add {
req.Operation = service.SetUsersRequest_Add
} else if *o.modify {
req.Operation = service.SetUsersRequest_Modify
} else if *o.delete {
req.Operation = service.SetUsersRequest_Delete
} else {
return common.NewError("Invalid operation")
}
err = stream.Send(req)
if err != nil {
return err
}
resp, err := stream.Recv()
if err != nil {
return err
}
if resp.Success {
fmt.Println("Done")
} else {
fmt.Println("Failed: " + resp.Info)
}
return nil
}
func (o *apiOption) Handle() error {
if *o.cmd == "" {
return common.NewError("")
}
conn, err := grpc.Dial(*o.address, grpc.WithInsecure())
if err != nil {
log.Error(err)
return nil
}
defer conn.Close()
apiClient := service.NewTrojanServerServiceClient(conn)
switch *o.cmd {
case "list":
err := o.listUsers(apiClient)
if err != nil {
log.Error(err)
}
case "get":
err := o.getUsers(apiClient)
if err != nil {
log.Error(err)
}
case "set":
err := o.setUsers(apiClient)
if err != nil {
log.Error(err)
}
default:
log.Error("Unknown command " + *o.cmd)
}
return nil
}
func (o *apiOption) Priority() int {
return 50
}
func init() {
common.RegisterOptionHandler(&apiOption{
cmd: flag.String("api", "", "Connect to a Trojan-Go API service. \"-api add/get/list\""),
address: flag.String("api-addr", "127.0.0.1:10000", "Address of Trojan-Go API service"),
password: flag.String("target-password", "", "Password of the target user"),
hash: flag.String("target-hash", "", "Hash of the target user"),
add: flag.Bool("add-profile", false, "Add a new profile with API"),
delete: flag.Bool("delete-profile", false, "Delete an existing profile with API"),
modify: flag.Bool("modify-profile", false, "Modify an existing profile with API"),
uploadSpeedLimit: flag.Int("upload-speed-limit", 0, "Limit the upload speed with API"),
downloadSpeedLimit: flag.Int("download-speed-limit", 0, "Limit the download speed with API"),
iplimit: flag.Int("ip-limit", 0, "Limit the number of IP with API"),
ctx: context.Background(),
})
}
+7
View File
@@ -0,0 +1,7 @@
package control
import "testing"
func TestControl(t *testing.T) {
}
-21
View File
@@ -1,21 +0,0 @@
package api
import "github.com/p4gefau1t/trojan-go/common"
// TODO implement api service client
type apiOption struct {
common.OptionHandler
}
func (apiOption) Name() string {
return "api"
}
func (o *apiOption) Handle() error {
return nil
}
func (o *apiOption) Priority() int {
return 50
}
+115 -115
View File
@@ -4,7 +4,7 @@
// protoc v3.11.4
// source: api.proto
package api
package service
import (
context "context"
@@ -29,52 +29,52 @@ const (
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type SetUserRequest_Operation int32
type SetUsersRequest_Operation int32
const (
SetUserRequest_Add SetUserRequest_Operation = 0
SetUserRequest_Delete SetUserRequest_Operation = 1
SetUserRequest_Modify SetUserRequest_Operation = 2
SetUsersRequest_Add SetUsersRequest_Operation = 0
SetUsersRequest_Delete SetUsersRequest_Operation = 1
SetUsersRequest_Modify SetUsersRequest_Operation = 2
)
// Enum value maps for SetUserRequest_Operation.
// Enum value maps for SetUsersRequest_Operation.
var (
SetUserRequest_Operation_name = map[int32]string{
SetUsersRequest_Operation_name = map[int32]string{
0: "Add",
1: "Delete",
2: "Modify",
}
SetUserRequest_Operation_value = map[string]int32{
SetUsersRequest_Operation_value = map[string]int32{
"Add": 0,
"Delete": 1,
"Modify": 2,
}
)
func (x SetUserRequest_Operation) Enum() *SetUserRequest_Operation {
p := new(SetUserRequest_Operation)
func (x SetUsersRequest_Operation) Enum() *SetUsersRequest_Operation {
p := new(SetUsersRequest_Operation)
*p = x
return p
}
func (x SetUserRequest_Operation) String() string {
func (x SetUsersRequest_Operation) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (SetUserRequest_Operation) Descriptor() protoreflect.EnumDescriptor {
func (SetUsersRequest_Operation) Descriptor() protoreflect.EnumDescriptor {
return file_api_proto_enumTypes[0].Descriptor()
}
func (SetUserRequest_Operation) Type() protoreflect.EnumType {
func (SetUsersRequest_Operation) Type() protoreflect.EnumType {
return &file_api_proto_enumTypes[0]
}
func (x SetUserRequest_Operation) Number() protoreflect.EnumNumber {
func (x SetUsersRequest_Operation) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use SetUserRequest_Operation.Descriptor instead.
func (SetUserRequest_Operation) EnumDescriptor() ([]byte, []int) {
// Deprecated: Use SetUsersRequest_Operation.Descriptor instead.
func (SetUsersRequest_Operation) EnumDescriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{10, 0}
}
@@ -659,19 +659,19 @@ func (x *GetUsersResponse) GetStatus() *UserStatus {
return nil
}
type SetUserRequest struct {
type SetUsersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
Operation SetUserRequest_Operation `protobuf:"varint,2,opt,name=operation,proto3,enum=trojan.api.SetUserRequest_Operation" json:"operation,omitempty"`
SpeedLimit *Speed `protobuf:"bytes,3,opt,name=speed_limit,json=speedLimit,proto3" json:"speed_limit,omitempty"`
IpLimit int32 `protobuf:"varint,4,opt,name=ip_limit,json=ipLimit,proto3" json:"ip_limit,omitempty"`
User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
Operation SetUsersRequest_Operation `protobuf:"varint,2,opt,name=operation,proto3,enum=trojan.api.SetUsersRequest_Operation" json:"operation,omitempty"`
SpeedLimit *Speed `protobuf:"bytes,3,opt,name=speed_limit,json=speedLimit,proto3" json:"speed_limit,omitempty"`
IpLimit int32 `protobuf:"varint,4,opt,name=ip_limit,json=ipLimit,proto3" json:"ip_limit,omitempty"`
}
func (x *SetUserRequest) Reset() {
*x = SetUserRequest{}
func (x *SetUsersRequest) Reset() {
*x = SetUsersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -679,13 +679,13 @@ func (x *SetUserRequest) Reset() {
}
}
func (x *SetUserRequest) String() string {
func (x *SetUsersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetUserRequest) ProtoMessage() {}
func (*SetUsersRequest) ProtoMessage() {}
func (x *SetUserRequest) ProtoReflect() protoreflect.Message {
func (x *SetUsersRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -697,40 +697,40 @@ func (x *SetUserRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use SetUserRequest.ProtoReflect.Descriptor instead.
func (*SetUserRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use SetUsersRequest.ProtoReflect.Descriptor instead.
func (*SetUsersRequest) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{10}
}
func (x *SetUserRequest) GetUser() *User {
func (x *SetUsersRequest) GetUser() *User {
if x != nil {
return x.User
}
return nil
}
func (x *SetUserRequest) GetOperation() SetUserRequest_Operation {
func (x *SetUsersRequest) GetOperation() SetUsersRequest_Operation {
if x != nil {
return x.Operation
}
return SetUserRequest_Add
return SetUsersRequest_Add
}
func (x *SetUserRequest) GetSpeedLimit() *Speed {
func (x *SetUsersRequest) GetSpeedLimit() *Speed {
if x != nil {
return x.SpeedLimit
}
return nil
}
func (x *SetUserRequest) GetIpLimit() int32 {
func (x *SetUsersRequest) GetIpLimit() int32 {
if x != nil {
return x.IpLimit
}
return 0
}
type SetUserResponse struct {
type SetUsersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
@@ -739,8 +739,8 @@ type SetUserResponse struct {
Info string `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
}
func (x *SetUserResponse) Reset() {
*x = SetUserResponse{}
func (x *SetUsersResponse) Reset() {
*x = SetUsersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -748,13 +748,13 @@ func (x *SetUserResponse) Reset() {
}
}
func (x *SetUserResponse) String() string {
func (x *SetUsersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetUserResponse) ProtoMessage() {}
func (*SetUsersResponse) ProtoMessage() {}
func (x *SetUserResponse) ProtoReflect() protoreflect.Message {
func (x *SetUsersResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -766,19 +766,19 @@ func (x *SetUserResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use SetUserResponse.ProtoReflect.Descriptor instead.
func (*SetUserResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use SetUsersResponse.ProtoReflect.Descriptor instead.
func (*SetUsersResponse) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{11}
}
func (x *SetUserResponse) GetSuccess() bool {
func (x *SetUsersResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *SetUserResponse) GetInfo() string {
func (x *SetUsersResponse) GetInfo() string {
if x != nil {
return x.Info
}
@@ -857,50 +857,50 @@ var file_api_proto_rawDesc = []byte{
0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73,
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61,
0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72,
0x12, 0x42, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x65, 0x64, 0x5f, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x72, 0x6f, 0x6a,
0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x52, 0x0a, 0x73, 0x70,
0x65, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x70, 0x5f, 0x6c,
0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x69, 0x70, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x10,
0x02, 0x22, 0x3f, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12,
0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e,
0x66, 0x6f, 0x32, 0x64, 0x0a, 0x13, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x47, 0x65, 0x74,
0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xfb, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x6f,
0x6a, 0x61, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x2e,
0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55,
0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x74, 0x72,
0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65,
0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4b,
0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x72, 0x6f,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x75,
0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x72, 0x6f, 0x6a,
0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65,
0x72, 0x12, 0x43, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x65, 0x64, 0x5f,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x72,
0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x52, 0x0a,
0x73, 0x70, 0x65, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x70,
0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x69, 0x70,
0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x2c, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x69, 0x66,
0x79, 0x10, 0x02, 0x22, 0x40, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65,
0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73,
0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x69, 0x6e, 0x66, 0x6f, 0x32, 0x64, 0x0a, 0x13, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a,
0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x6f,
0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x66, 0x66,
0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x72, 0x6f, 0x6a,
0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69,
0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xfd, 0x01, 0x0a, 0x13,
0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73,
0x12, 0x1c, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x4b, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e,
0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73,
0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x72, 0x6f,
0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4b,
0x0a, 0x08, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x74, 0x72, 0x6f,
0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x49, 0x0a, 0x08, 0x53,
0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x0b, 0x5a, 0x09, 0x2e,
0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -918,19 +918,19 @@ func file_api_proto_rawDescGZIP() []byte {
var file_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_api_proto_goTypes = []interface{}{
(SetUserRequest_Operation)(0), // 0: trojan.api.SetUserRequest.Operation
(*Traffic)(nil), // 1: trojan.api.Traffic
(*Speed)(nil), // 2: trojan.api.Speed
(*User)(nil), // 3: trojan.api.User
(*UserStatus)(nil), // 4: trojan.api.UserStatus
(*GetTrafficRequest)(nil), // 5: trojan.api.GetTrafficRequest
(*GetTrafficResponse)(nil), // 6: trojan.api.GetTrafficResponse
(*ListUsersRequest)(nil), // 7: trojan.api.ListUsersRequest
(*ListUsersResponse)(nil), // 8: trojan.api.ListUsersResponse
(*GetUsersRequest)(nil), // 9: trojan.api.GetUsersRequest
(*GetUsersResponse)(nil), // 10: trojan.api.GetUsersResponse
(*SetUserRequest)(nil), // 11: trojan.api.SetUserRequest
(*SetUserResponse)(nil), // 12: trojan.api.SetUserResponse
(SetUsersRequest_Operation)(0), // 0: trojan.api.SetUsersRequest.Operation
(*Traffic)(nil), // 1: trojan.api.Traffic
(*Speed)(nil), // 2: trojan.api.Speed
(*User)(nil), // 3: trojan.api.User
(*UserStatus)(nil), // 4: trojan.api.UserStatus
(*GetTrafficRequest)(nil), // 5: trojan.api.GetTrafficRequest
(*GetTrafficResponse)(nil), // 6: trojan.api.GetTrafficResponse
(*ListUsersRequest)(nil), // 7: trojan.api.ListUsersRequest
(*ListUsersResponse)(nil), // 8: trojan.api.ListUsersResponse
(*GetUsersRequest)(nil), // 9: trojan.api.GetUsersRequest
(*GetUsersResponse)(nil), // 10: trojan.api.GetUsersResponse
(*SetUsersRequest)(nil), // 11: trojan.api.SetUsersRequest
(*SetUsersResponse)(nil), // 12: trojan.api.SetUsersResponse
}
var file_api_proto_depIdxs = []int32{
3, // 0: trojan.api.UserStatus.user:type_name -> trojan.api.User
@@ -945,17 +945,17 @@ var file_api_proto_depIdxs = []int32{
3, // 9: trojan.api.GetUsersRequest.user:type_name -> trojan.api.User
3, // 10: trojan.api.GetUsersResponse.user:type_name -> trojan.api.User
4, // 11: trojan.api.GetUsersResponse.status:type_name -> trojan.api.UserStatus
3, // 12: trojan.api.SetUserRequest.user:type_name -> trojan.api.User
0, // 13: trojan.api.SetUserRequest.operation:type_name -> trojan.api.SetUserRequest.Operation
2, // 14: trojan.api.SetUserRequest.speed_limit:type_name -> trojan.api.Speed
3, // 12: trojan.api.SetUsersRequest.user:type_name -> trojan.api.User
0, // 13: trojan.api.SetUsersRequest.operation:type_name -> trojan.api.SetUsersRequest.Operation
2, // 14: trojan.api.SetUsersRequest.speed_limit:type_name -> trojan.api.Speed
5, // 15: trojan.api.TrojanClientService.GetTraffic:input_type -> trojan.api.GetTrafficRequest
7, // 16: trojan.api.TrojanServerService.ListUsers:input_type -> trojan.api.ListUsersRequest
9, // 17: trojan.api.TrojanServerService.GetUsers:input_type -> trojan.api.GetUsersRequest
11, // 18: trojan.api.TrojanServerService.SetUsers:input_type -> trojan.api.SetUserRequest
11, // 18: trojan.api.TrojanServerService.SetUsers:input_type -> trojan.api.SetUsersRequest
6, // 19: trojan.api.TrojanClientService.GetTraffic:output_type -> trojan.api.GetTrafficResponse
8, // 20: trojan.api.TrojanServerService.ListUsers:output_type -> trojan.api.ListUsersResponse
10, // 21: trojan.api.TrojanServerService.GetUsers:output_type -> trojan.api.GetUsersResponse
12, // 22: trojan.api.TrojanServerService.SetUsers:output_type -> trojan.api.SetUserResponse
12, // 22: trojan.api.TrojanServerService.SetUsers:output_type -> trojan.api.SetUsersResponse
19, // [19:23] is the sub-list for method output_type
15, // [15:19] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
@@ -1090,7 +1090,7 @@ func file_api_proto_init() {
}
}
file_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetUserRequest); i {
switch v := v.(*SetUsersRequest); i {
case 0:
return &v.state
case 1:
@@ -1102,7 +1102,7 @@ func file_api_proto_init() {
}
}
file_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetUserResponse); i {
switch v := v.(*SetUsersResponse); i {
case 0:
return &v.state
case 1:
@@ -1308,8 +1308,8 @@ func (c *trojanServerServiceClient) SetUsers(ctx context.Context, opts ...grpc.C
}
type TrojanServerService_SetUsersClient interface {
Send(*SetUserRequest) error
Recv() (*SetUserResponse, error)
Send(*SetUsersRequest) error
Recv() (*SetUsersResponse, error)
grpc.ClientStream
}
@@ -1317,12 +1317,12 @@ type trojanServerServiceSetUsersClient struct {
grpc.ClientStream
}
func (x *trojanServerServiceSetUsersClient) Send(m *SetUserRequest) error {
func (x *trojanServerServiceSetUsersClient) Send(m *SetUsersRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *trojanServerServiceSetUsersClient) Recv() (*SetUserResponse, error) {
m := new(SetUserResponse)
func (x *trojanServerServiceSetUsersClient) Recv() (*SetUsersResponse, error) {
m := new(SetUsersResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
@@ -1409,8 +1409,8 @@ func _TrojanServerService_SetUsers_Handler(srv interface{}, stream grpc.ServerSt
}
type TrojanServerService_SetUsersServer interface {
Send(*SetUserResponse) error
Recv() (*SetUserRequest, error)
Send(*SetUsersResponse) error
Recv() (*SetUsersRequest, error)
grpc.ServerStream
}
@@ -1418,12 +1418,12 @@ type trojanServerServiceSetUsersServer struct {
grpc.ServerStream
}
func (x *trojanServerServiceSetUsersServer) Send(m *SetUserResponse) error {
func (x *trojanServerServiceSetUsersServer) Send(m *SetUsersResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *trojanServerServiceSetUsersServer) Recv() (*SetUserRequest, error) {
m := new(SetUserRequest)
func (x *trojanServerServiceSetUsersServer) Recv() (*SetUsersRequest, error) {
m := new(SetUsersRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
+4 -4
View File
@@ -1,6 +1,6 @@
syntax = "proto3";
package trojan.api;
option go_package = ".;api";
option go_package = ".;service";
message Traffic {
uint64 upload_traffic = 1;
@@ -57,7 +57,7 @@ message GetUsersResponse {
UserStatus status = 4;
}
message SetUserRequest {
message SetUsersRequest {
User user = 1;
enum Operation {
Add = 0;
@@ -69,7 +69,7 @@ message SetUserRequest {
int32 ip_limit = 4;
}
message SetUserResponse {
message SetUsersResponse {
bool success = 1;
string info = 2;
}
@@ -84,5 +84,5 @@ service TrojanServerService {
// obtain specified user's info
rpc GetUsers(stream GetUsersRequest) returns(stream GetUsersResponse){}
// setup exsisting users' config
rpc SetUsers(stream SetUserRequest) returns(stream SetUserResponse){}
rpc SetUsers(stream SetUsersRequest) returns(stream SetUsersResponse){}
}
+1 -1
View File
@@ -1,4 +1,4 @@
package api
package service
import (
"context"
@@ -1,4 +1,4 @@
package api
package service
import (
"context"
View File
+6 -6
View File
@@ -1,4 +1,4 @@
package api
package service
import (
"context"
@@ -92,7 +92,7 @@ func (s *ServerAPI) SetUsers(stream TrojanServerService_SetUsersServer) error {
req.User.Hash = common.SHA224String(req.User.Password)
}
switch req.Operation {
case SetUserRequest_Add:
case SetUsersRequest_Add:
err = s.auth.AddUser(req.User.Hash)
if req.SpeedLimit != nil {
valid, user := s.auth.AuthUser(req.User.Hash)
@@ -101,9 +101,9 @@ func (s *ServerAPI) SetUsers(stream TrojanServerService_SetUsersServer) error {
}
user.SetSpeedLimit(int(req.SpeedLimit.DownloadSpeed), int(req.SpeedLimit.UploadSpeed))
}
case SetUserRequest_Delete:
case SetUsersRequest_Delete:
err = s.auth.DelUser(req.User.Hash)
case SetUserRequest_Modify:
case SetUsersRequest_Modify:
valid, user := s.auth.AuthUser(req.User.Hash)
if !valid {
err = common.NewError("Invalid user " + req.User.Hash)
@@ -117,13 +117,13 @@ func (s *ServerAPI) SetUsers(stream TrojanServerService_SetUsersServer) error {
}
}
if err != nil {
stream.Send(&SetUserResponse{
stream.Send(&SetUsersResponse{
Success: false,
Info: err.Error(),
})
continue
}
stream.Send(&SetUserResponse{
stream.Send(&SetUsersResponse{
Success: true,
})
}
@@ -1,4 +1,4 @@
package api
package service
import (
"context"
@@ -61,11 +61,11 @@ func TestServerAPI(t *testing.T) {
}
stream3, err := server.SetUsers(ctx)
stream3.Send(&SetUserRequest{
stream3.Send(&SetUsersRequest{
User: &User{
Hash: "hash1234",
},
Operation: SetUserRequest_Delete,
Operation: SetUsersRequest_Delete,
})
resp3, err := stream3.Recv()
if err != nil || !resp3.Success {
@@ -75,11 +75,11 @@ func TestServerAPI(t *testing.T) {
if valid {
t.Fail()
}
stream3.Send(&SetUserRequest{
stream3.Send(&SetUsersRequest{
User: &User{
Hash: "newhash",
},
Operation: SetUserRequest_Add,
Operation: SetUsersRequest_Add,
})
resp3, err = stream3.Recv()
if err != nil || !resp3.Success {
@@ -89,11 +89,11 @@ func TestServerAPI(t *testing.T) {
if !valid {
t.Fail()
}
stream3.Send(&SetUserRequest{
stream3.Send(&SetUsersRequest{
User: &User{
Hash: "newhash",
},
Operation: SetUserRequest_Modify,
Operation: SetUsersRequest_Modify,
SpeedLimit: &Speed{
DownloadSpeed: 5000,
UploadSpeed: 3000,
+2 -1
View File
@@ -3,5 +3,6 @@
package build
import (
_ "github.com/p4gefau1t/trojan-go/api"
_ "github.com/p4gefau1t/trojan-go/api/control"
_ "github.com/p4gefau1t/trojan-go/api/service"
)
-1
View File
@@ -10,7 +10,6 @@ import (
)
func main() {
log.Info("Trojan-Go", common.Version)
flag.Parse()
for {
h, err := common.PopOptionHandler()
+1
View File
@@ -24,6 +24,7 @@ func (*proxyOption) Priority() int {
}
func (c *proxyOption) Handle() error {
log.Info("Trojan-Go", common.Version)
log.Info("Loading config file from", *c.path)
//exit code 23 stands for initializing error, and systemd will not trying to restart it
+91
View File
@@ -0,0 +1,91 @@
package test
import (
"context"
"fmt"
"testing"
"time"
"github.com/p4gefau1t/trojan-go/api/service"
"github.com/p4gefau1t/trojan-go/common"
"golang.org/x/net/proxy"
"google.golang.org/grpc"
)
func TestServerAPI(t *testing.T) {
serverConfig := addAPIConfig(getBasicServerConfig())
clientConfig := getBasicClientConfig()
clientConfig.Hash = getHash("apitest")
clientConfig.Passwords = getPasswords("apitest")
ctx, cancel := context.WithCancel(context.Background())
go RunBlackHoleTCPServer(ctx)
go RunServer(ctx, serverConfig)
go RunClient(ctx, clientConfig)
time.Sleep(time.Second * 2)
grpcConn, err := grpc.Dial("127.0.0.1:10000", grpc.WithInsecure())
common.Must(err)
server := service.NewTrojanServerServiceClient(grpcConn)
listUserStream, err := server.ListUsers(ctx, &service.ListUsersRequest{})
common.Must(err)
defer listUserStream.CloseSend()
for {
resp, err := listUserStream.Recv()
if err != nil {
break
}
fmt.Println(resp.User.Hash)
fmt.Println(*resp.Status.SpeedCurrent)
fmt.Println(*resp.Status.SpeedLimit)
}
listUserStream.CloseSend()
setUserStream, err := server.SetUsers(ctx)
setUserStream.Send(&service.SetUsersRequest{
User: &service.User{
Hash: common.SHA224String("apitest"),
},
SpeedLimit: &service.Speed{
UploadSpeed: 1024 * 1024 * 2,
},
Operation: service.SetUsersRequest_Add,
})
resp3, err := setUserStream.Recv()
if err != nil || !resp3.Success {
t.Fail()
}
setUserStream.CloseSend()
go func() {
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:4444", nil, nil)
common.Must(err)
conn, err := dialer.Dial("tcp", "127.0.0.1:5000")
common.Must(err)
mbytes := 16
payload := GeneratePayload(1024 * 1024 * mbytes)
t1 := time.Now()
conn.Write(payload)
t2 := time.Now()
speed := float64(mbytes) / t2.Sub(t1).Seconds()
t.Log("single-thread link speed:", speed, "MiB/s")
conn.Close()
}()
time.Sleep(time.Second * 5)
listUserStream, err = server.ListUsers(ctx, &service.ListUsersRequest{})
common.Must(err)
defer listUserStream.CloseSend()
for {
resp, err := listUserStream.Recv()
if err != nil {
break
}
fmt.Println(resp.User.Hash)
fmt.Println(resp.Status.SpeedCurrent.UploadSpeed)
fmt.Println(resp.Status.SpeedLimit.UploadSpeed)
}
listUserStream.CloseSend()
cancel()
}
+1 -80
View File
@@ -17,7 +17,7 @@ import (
"net/http"
_ "net/http/pprof"
"github.com/p4gefau1t/trojan-go/api"
_ "github.com/p4gefau1t/trojan-go/api/service"
"github.com/p4gefau1t/trojan-go/common"
"github.com/p4gefau1t/trojan-go/conf"
_ "github.com/p4gefau1t/trojan-go/log/golog"
@@ -30,7 +30,6 @@ import (
_ "github.com/p4gefau1t/trojan-go/stat/mysql"
"golang.org/x/net/proxy"
"golang.org/x/net/websocket"
"google.golang.org/grpc"
)
var cert string = `
@@ -556,84 +555,6 @@ func TestMySQL(t *testing.T) {
CheckClientServer(t, clientConfig, serverConfig)
}
func TestServerAPI(t *testing.T) {
serverConfig := addAPIConfig(getBasicServerConfig())
clientConfig := getBasicClientConfig()
clientConfig.Hash = getHash("apitest")
clientConfig.Passwords = getPasswords("apitest")
ctx, cancel := context.WithCancel(context.Background())
go RunBlackHoleTCPServer(ctx)
go RunServer(ctx, serverConfig)
go RunClient(ctx, clientConfig)
time.Sleep(time.Second * 2)
grpcConn, err := grpc.Dial("127.0.0.1:10000", grpc.WithInsecure())
common.Must(err)
server := api.NewTrojanServerServiceClient(grpcConn)
listUserStream, err := server.ListUsers(ctx, &api.ListUsersRequest{})
common.Must(err)
defer listUserStream.CloseSend()
for {
resp, err := listUserStream.Recv()
if err != nil {
break
}
fmt.Println(resp.User.Hash)
fmt.Println(*resp.Status.SpeedCurrent)
fmt.Println(*resp.Status.SpeedLimit)
}
listUserStream.CloseSend()
setUserStream, err := server.SetUsers(ctx)
setUserStream.Send(&api.SetUserRequest{
User: &api.User{
Hash: common.SHA224String("apitest"),
},
SpeedLimit: &api.Speed{
UploadSpeed: 1024 * 1024 * 2,
},
Operation: api.SetUserRequest_Add,
})
resp3, err := setUserStream.Recv()
if err != nil || !resp3.Success {
t.Fail()
}
setUserStream.CloseSend()
go func() {
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:4444", nil, nil)
common.Must(err)
conn, err := dialer.Dial("tcp", "127.0.0.1:5000")
common.Must(err)
mbytes := 16
payload := GeneratePayload(1024 * 1024 * mbytes)
t1 := time.Now()
conn.Write(payload)
t2 := time.Now()
speed := float64(mbytes) / t2.Sub(t1).Seconds()
t.Log("single-thread link speed:", speed, "MiB/s")
conn.Close()
}()
time.Sleep(time.Second * 5)
listUserStream, err = server.ListUsers(ctx, &api.ListUsersRequest{})
common.Must(err)
defer listUserStream.CloseSend()
for {
resp, err := listUserStream.Recv()
if err != nil {
break
}
fmt.Println(resp.User.Hash)
fmt.Println(resp.Status.SpeedCurrent.UploadSpeed)
fmt.Println(resp.Status.SpeedLimit.UploadSpeed)
}
listUserStream.CloseSend()
cancel()
}
func TestDNS(t *testing.T) {
serverConfig := addDNSConfig(getBasicServerConfig())
clientConfig := getBasicClientConfig()