From 8bc0679b5c15d44d90f52d508dca85680867fd99 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Thu, 28 Sep 2023 21:02:11 +0800 Subject: [PATCH] add hop plugin --- bypass/proto/bypass.pb.go | 44 +++++-- bypass/proto/bypass.proto | 2 + hop/example/grpc/main.go | 80 +++++++++++++ hop/example/http/main.go | 93 +++++++++++++++ hop/proto/hop.pb.go | 243 ++++++++++++++++++++++++++++++++++++++ hop/proto/hop.proto | 22 ++++ hop/proto/hop_grpc.pb.go | 105 ++++++++++++++++ 7 files changed, 576 insertions(+), 13 deletions(-) create mode 100644 hop/example/grpc/main.go create mode 100644 hop/example/http/main.go create mode 100644 hop/proto/hop.pb.go create mode 100644 hop/proto/hop.proto create mode 100644 hop/proto/hop_grpc.pb.go diff --git a/bypass/proto/bypass.pb.go b/bypass/proto/bypass.pb.go index d937a19..b970580 100644 --- a/bypass/proto/bypass.pb.go +++ b/bypass/proto/bypass.pb.go @@ -29,8 +29,10 @@ type BypassRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - Client string `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Client string `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` + Network string `protobuf:"bytes,3,opt,name=network,proto3" json:"network,omitempty"` + Host string `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"` } func (x *BypassRequest) Reset() { @@ -79,6 +81,20 @@ func (x *BypassRequest) GetClient() string { return "" } +func (x *BypassRequest) GetNetwork() string { + if x != nil { + return x.Network + } + return "" +} + +func (x *BypassRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + type BypassReply struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -130,20 +146,22 @@ var File_bypass_proto protoreflect.FileDescriptor var file_bypass_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3b, 0x0a, 0x0d, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x0d, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x0b, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, - 0x6b, 0x32, 0x3c, 0x0a, 0x06, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x06, 0x42, - 0x79, 0x70, 0x61, 0x73, 0x73, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x79, - 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, - 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, - 0x2d, 0x67, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x62, 0x79, 0x70, - 0x61, 0x73, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x22, 0x1d, 0x0a, 0x0b, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x32, + 0x3c, 0x0a, 0x06, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x06, 0x42, 0x79, 0x70, + 0x61, 0x73, 0x73, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x79, 0x70, 0x61, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x42, 0x79, 0x70, 0x61, 0x73, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x28, 0x5a, + 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x67, + 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x62, 0x79, 0x70, 0x61, 0x73, + 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/bypass/proto/bypass.proto b/bypass/proto/bypass.proto index 3060432..5ebd5a1 100644 --- a/bypass/proto/bypass.proto +++ b/bypass/proto/bypass.proto @@ -9,6 +9,8 @@ option go_package = "github.com/go-gost/plugin/bypass/proto"; message BypassRequest { string addr = 1; string client = 2; + string network = 3; + string host = 4; } message BypassReply { diff --git a/hop/example/grpc/main.go b/hop/example/grpc/main.go new file mode 100644 index 0000000..599c218 --- /dev/null +++ b/hop/example/grpc/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "log" + "net" + "sync/atomic" + + "github.com/go-gost/plugin/hop/proto" + "github.com/go-gost/x/config" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +var ( + nodes = []*config.NodeConfig{ + { + Name: "node-0", + Addr: ":8888", + Connector: &config.ConnectorConfig{ + Type: "socks5", + Auth: &config.AuthConfig{ + Username: "user", + Password: "pass", + }, + }, + Dialer: &config.DialerConfig{ + Type: "tcp", + }, + }, + { + Name: "node-1", + Addr: ":9999", + Connector: &config.ConnectorConfig{ + Type: "http", + Auth: &config.AuthConfig{ + Username: "user", + Password: "pass", + }, + }, + Dialer: &config.DialerConfig{ + Type: "tcp", + }, + }, + } +) + +type server struct { + counter atomic.Uint64 + proto.UnimplementedHopServer +} + +func (s *server) Select(ctx context.Context, in *proto.SelectRequest) (*proto.SelectReply, error) { + node := nodes[s.counter.Add(1)%uint64(len(nodes))] + v, _ := json.Marshal(node) + reply := &proto.SelectReply{ + Node: v, + } + return reply, nil +} + +func main() { + flag.Parse() + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + proto.RegisterHopServer(s, &server{}) + log.Printf("server listening at %v", lis.Addr()) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/hop/example/http/main.go b/hop/example/http/main.go new file mode 100644 index 0000000..934fa93 --- /dev/null +++ b/hop/example/http/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "log" + "net" + "net/http" + "sync/atomic" + + "github.com/go-gost/x/config" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +var ( + nodes = []*config.NodeConfig{ + { + Name: "node-0", + Addr: ":8888", + Connector: &config.ConnectorConfig{ + Type: "socks5", + Auth: &config.AuthConfig{ + Username: "user", + Password: "pass", + }, + }, + Dialer: &config.DialerConfig{ + Type: "tcp", + }, + }, + { + Name: "node-1", + Addr: ":9999", + Connector: &config.ConnectorConfig{ + Type: "http", + Auth: &config.AuthConfig{ + Username: "user", + Password: "pass", + }, + }, + Dialer: &config.DialerConfig{ + Type: "tcp", + }, + }, + } +) + +type hopRequest struct { + Network string `json:"network"` + Addr string `json:"addr"` + Host string `json:"host"` + Client string `json:"client"` +} + +type hopResponse struct { + Node string `json:"node"` +} + +func main() { + flag.Parse() + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + log.Printf("server listening at %v", lis.Addr()) + + var counter atomic.Uint64 + + http.HandleFunc("/hop", func(w http.ResponseWriter, r *http.Request) { + rb := hopRequest{} + if err := json.NewDecoder(r.Body).Decode(&rb); err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + log.Printf("hop: %s %s %s %s", rb.Network, rb.Addr, rb.Host, rb.Client) + + node := nodes[counter.Add(1)%uint64(len(nodes))] + v, _ := json.Marshal(node) + + resp := hopResponse{Node: string(v)} + + json.NewEncoder(w).Encode(resp) + }) + + if err := http.Serve(lis, nil); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/hop/proto/hop.pb.go b/hop/proto/hop.pb.go new file mode 100644 index 0000000..fa95f95 --- /dev/null +++ b/hop/proto/hop.pb.go @@ -0,0 +1,243 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// hop.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.15.8 +// source: hop.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SelectRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` + Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` + Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"` + Client string `protobuf:"bytes,4,opt,name=client,proto3" json:"client,omitempty"` +} + +func (x *SelectRequest) Reset() { + *x = SelectRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_hop_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SelectRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelectRequest) ProtoMessage() {} + +func (x *SelectRequest) ProtoReflect() protoreflect.Message { + mi := &file_hop_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelectRequest.ProtoReflect.Descriptor instead. +func (*SelectRequest) Descriptor() ([]byte, []int) { + return file_hop_proto_rawDescGZIP(), []int{0} +} + +func (x *SelectRequest) GetNetwork() string { + if x != nil { + return x.Network + } + return "" +} + +func (x *SelectRequest) GetAddr() string { + if x != nil { + return x.Addr + } + return "" +} + +func (x *SelectRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *SelectRequest) GetClient() string { + if x != nil { + return x.Client + } + return "" +} + +type SelectReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node []byte `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` +} + +func (x *SelectReply) Reset() { + *x = SelectReply{} + if protoimpl.UnsafeEnabled { + mi := &file_hop_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SelectReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelectReply) ProtoMessage() {} + +func (x *SelectReply) ProtoReflect() protoreflect.Message { + mi := &file_hop_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelectReply.ProtoReflect.Descriptor instead. +func (*SelectReply) Descriptor() ([]byte, []int) { + return file_hop_proto_rawDescGZIP(), []int{1} +} + +func (x *SelectReply) GetNode() []byte { + if x != nil { + return x.Node + } + return nil +} + +var File_hop_proto protoreflect.FileDescriptor + +var file_hop_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x68, 0x6f, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x0d, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, + 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x21, 0x0a, + 0x0b, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x32, 0x39, 0x0a, 0x03, 0x48, 0x6f, 0x70, 0x12, 0x32, 0x0a, 0x06, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x25, 0x5a, 0x23, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x67, 0x6f, 0x73, + 0x74, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x68, 0x6f, 0x70, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_hop_proto_rawDescOnce sync.Once + file_hop_proto_rawDescData = file_hop_proto_rawDesc +) + +func file_hop_proto_rawDescGZIP() []byte { + file_hop_proto_rawDescOnce.Do(func() { + file_hop_proto_rawDescData = protoimpl.X.CompressGZIP(file_hop_proto_rawDescData) + }) + return file_hop_proto_rawDescData +} + +var file_hop_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_hop_proto_goTypes = []interface{}{ + (*SelectRequest)(nil), // 0: proto.SelectRequest + (*SelectReply)(nil), // 1: proto.SelectReply +} +var file_hop_proto_depIdxs = []int32{ + 0, // 0: proto.Hop.Select:input_type -> proto.SelectRequest + 1, // 1: proto.Hop.Select:output_type -> proto.SelectReply + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hop_proto_init() } +func file_hop_proto_init() { + if File_hop_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_hop_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SelectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hop_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SelectReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_hop_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_hop_proto_goTypes, + DependencyIndexes: file_hop_proto_depIdxs, + MessageInfos: file_hop_proto_msgTypes, + }.Build() + File_hop_proto = out.File + file_hop_proto_rawDesc = nil + file_hop_proto_goTypes = nil + file_hop_proto_depIdxs = nil +} diff --git a/hop/proto/hop.proto b/hop/proto/hop.proto new file mode 100644 index 0000000..1091723 --- /dev/null +++ b/hop/proto/hop.proto @@ -0,0 +1,22 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// hop.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/hop/proto"; + +message SelectRequest { + string network = 1; + string addr = 2; + string host = 3; + string client = 4; +} + +message SelectReply { + bytes node = 1; +} + +service Hop { + rpc Select(SelectRequest) returns (SelectReply); +} diff --git a/hop/proto/hop_grpc.pb.go b/hop/proto/hop_grpc.pb.go new file mode 100644 index 0000000..b53e946 --- /dev/null +++ b/hop/proto/hop_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.15.8 +// source: hop.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// HopClient is the client API for Hop service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HopClient interface { + Select(ctx context.Context, in *SelectRequest, opts ...grpc.CallOption) (*SelectReply, error) +} + +type hopClient struct { + cc grpc.ClientConnInterface +} + +func NewHopClient(cc grpc.ClientConnInterface) HopClient { + return &hopClient{cc} +} + +func (c *hopClient) Select(ctx context.Context, in *SelectRequest, opts ...grpc.CallOption) (*SelectReply, error) { + out := new(SelectReply) + err := c.cc.Invoke(ctx, "/proto.Hop/Select", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HopServer is the server API for Hop service. +// All implementations must embed UnimplementedHopServer +// for forward compatibility +type HopServer interface { + Select(context.Context, *SelectRequest) (*SelectReply, error) + mustEmbedUnimplementedHopServer() +} + +// UnimplementedHopServer must be embedded to have forward compatible implementations. +type UnimplementedHopServer struct { +} + +func (UnimplementedHopServer) Select(context.Context, *SelectRequest) (*SelectReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Select not implemented") +} +func (UnimplementedHopServer) mustEmbedUnimplementedHopServer() {} + +// UnsafeHopServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HopServer will +// result in compilation errors. +type UnsafeHopServer interface { + mustEmbedUnimplementedHopServer() +} + +func RegisterHopServer(s grpc.ServiceRegistrar, srv HopServer) { + s.RegisterService(&Hop_ServiceDesc, srv) +} + +func _Hop_Select_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SelectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HopServer).Select(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Hop/Select", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HopServer).Select(ctx, req.(*SelectRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Hop_ServiceDesc is the grpc.ServiceDesc for Hop service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Hop_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Hop", + HandlerType: (*HopServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Select", + Handler: _Hop_Select_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "hop.proto", +}