From d221a4ec9a986964b3531ef49561ca512c0ac389 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Tue, 18 Apr 2023 20:21:06 +0800 Subject: [PATCH] initial commit --- admission/example/main.go | 43 +++++ admission/proto/admission.pb.go | 216 +++++++++++++++++++++++++ admission/proto/admission.proto | 19 +++ admission/proto/admission_grpc.pb.go | 101 ++++++++++++ auth/example/main.go | 43 +++++ auth/proto/auth.pb.go | 227 ++++++++++++++++++++++++++ auth/proto/auth.proto | 20 +++ auth/proto/auth_grpc.pb.go | 101 ++++++++++++ bypass/example/main.go | 43 +++++ bypass/proto/bypass.pb.go | 215 ++++++++++++++++++++++++ bypass/proto/bypass.proto | 19 +++ bypass/proto/bypass_grpc.pb.go | 101 ++++++++++++ go.mod | 16 ++ go.sum | 20 +++ hosts/example/main.go | 44 +++++ hosts/proto/hosts.pb.go | 234 +++++++++++++++++++++++++++ hosts/proto/hosts.proto | 21 +++ hosts/proto/hosts_grpc.pb.go | 101 ++++++++++++ ingress/example/main.go | 40 +++++ ingress/proto/ingress.pb.go | 215 ++++++++++++++++++++++++ ingress/proto/ingress.proto | 19 +++ ingress/proto/ingress_grpc.pb.go | 101 ++++++++++++ recorder/example/main.go | 42 +++++ recorder/proto/recorder.pb.go | 215 ++++++++++++++++++++++++ recorder/proto/recorder.proto | 19 +++ recorder/proto/recorder_grpc.pb.go | 101 ++++++++++++ resolver/example/main.go | 44 +++++ resolver/proto/resolver.pb.go | 234 +++++++++++++++++++++++++++ resolver/proto/resolver.proto | 21 +++ resolver/proto/resolver_grpc.pb.go | 101 ++++++++++++ 30 files changed, 2736 insertions(+) create mode 100644 admission/example/main.go create mode 100644 admission/proto/admission.pb.go create mode 100644 admission/proto/admission.proto create mode 100644 admission/proto/admission_grpc.pb.go create mode 100644 auth/example/main.go create mode 100644 auth/proto/auth.pb.go create mode 100644 auth/proto/auth.proto create mode 100644 auth/proto/auth_grpc.pb.go create mode 100644 bypass/example/main.go create mode 100644 bypass/proto/bypass.pb.go create mode 100644 bypass/proto/bypass.proto create mode 100644 bypass/proto/bypass_grpc.pb.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 hosts/example/main.go create mode 100644 hosts/proto/hosts.pb.go create mode 100644 hosts/proto/hosts.proto create mode 100644 hosts/proto/hosts_grpc.pb.go create mode 100644 ingress/example/main.go create mode 100644 ingress/proto/ingress.pb.go create mode 100644 ingress/proto/ingress.proto create mode 100644 ingress/proto/ingress_grpc.pb.go create mode 100644 recorder/example/main.go create mode 100644 recorder/proto/recorder.pb.go create mode 100644 recorder/proto/recorder.proto create mode 100644 recorder/proto/recorder_grpc.pb.go create mode 100644 resolver/example/main.go create mode 100644 resolver/proto/resolver.pb.go create mode 100644 resolver/proto/resolver.proto create mode 100644 resolver/proto/resolver_grpc.pb.go diff --git a/admission/example/main.go b/admission/example/main.go new file mode 100644 index 0000000..dec8b7a --- /dev/null +++ b/admission/example/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/admission/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedAdmissionServer +} + +func (s *server) Admit(ctx context.Context, in *proto.AdmissionRequest) (*proto.AdmissionReply, error) { + reply := &proto.AdmissionReply{} + if in.GetAddr() == "127.0.0.1" { + reply.Ok = true + } + log.Printf("admission: %s, %v", in.GetAddr(), reply.Ok) + 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.RegisterAdmissionServer(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/admission/proto/admission.pb.go b/admission/proto/admission.pb.go new file mode 100644 index 0000000..4d0194a --- /dev/null +++ b/admission/proto/admission.pb.go @@ -0,0 +1,216 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// admission.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: admission.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 AdmissionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` +} + +func (x *AdmissionRequest) Reset() { + *x = AdmissionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_admission_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdmissionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdmissionRequest) ProtoMessage() {} + +func (x *AdmissionRequest) ProtoReflect() protoreflect.Message { + mi := &file_admission_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 AdmissionRequest.ProtoReflect.Descriptor instead. +func (*AdmissionRequest) Descriptor() ([]byte, []int) { + return file_admission_proto_rawDescGZIP(), []int{0} +} + +func (x *AdmissionRequest) GetAddr() string { + if x != nil { + return x.Addr + } + return "" +} + +type AdmissionReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *AdmissionReply) Reset() { + *x = AdmissionReply{} + if protoimpl.UnsafeEnabled { + mi := &file_admission_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdmissionReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdmissionReply) ProtoMessage() {} + +func (x *AdmissionReply) ProtoReflect() protoreflect.Message { + mi := &file_admission_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 AdmissionReply.ProtoReflect.Descriptor instead. +func (*AdmissionReply) Descriptor() ([]byte, []int) { + return file_admission_proto_rawDescGZIP(), []int{1} +} + +func (x *AdmissionReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +var File_admission_proto protoreflect.FileDescriptor + +var file_admission_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, 0x0a, 0x10, 0x41, 0x64, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, + 0x22, 0x20, 0x0a, 0x0e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, + 0x6f, 0x6b, 0x32, 0x44, 0x0a, 0x09, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x37, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x2b, 0x5a, 0x29, 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, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_admission_proto_rawDescOnce sync.Once + file_admission_proto_rawDescData = file_admission_proto_rawDesc +) + +func file_admission_proto_rawDescGZIP() []byte { + file_admission_proto_rawDescOnce.Do(func() { + file_admission_proto_rawDescData = protoimpl.X.CompressGZIP(file_admission_proto_rawDescData) + }) + return file_admission_proto_rawDescData +} + +var file_admission_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_admission_proto_goTypes = []interface{}{ + (*AdmissionRequest)(nil), // 0: proto.AdmissionRequest + (*AdmissionReply)(nil), // 1: proto.AdmissionReply +} +var file_admission_proto_depIdxs = []int32{ + 0, // 0: proto.Admission.Admit:input_type -> proto.AdmissionRequest + 1, // 1: proto.Admission.Admit:output_type -> proto.AdmissionReply + 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_admission_proto_init() } +func file_admission_proto_init() { + if File_admission_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_admission_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdmissionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_admission_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdmissionReply); 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_admission_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_admission_proto_goTypes, + DependencyIndexes: file_admission_proto_depIdxs, + MessageInfos: file_admission_proto_msgTypes, + }.Build() + File_admission_proto = out.File + file_admission_proto_rawDesc = nil + file_admission_proto_goTypes = nil + file_admission_proto_depIdxs = nil +} diff --git a/admission/proto/admission.proto b/admission/proto/admission.proto new file mode 100644 index 0000000..35343a7 --- /dev/null +++ b/admission/proto/admission.proto @@ -0,0 +1,19 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// admission.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/admission/proto"; + +message AdmissionRequest { + string addr = 1; +} + +message AdmissionReply { + bool ok = 1; +} + +service Admission { + rpc Admit(AdmissionRequest) returns (AdmissionReply); +} diff --git a/admission/proto/admission_grpc.pb.go b/admission/proto/admission_grpc.pb.go new file mode 100644 index 0000000..e44c467 --- /dev/null +++ b/admission/proto/admission_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// AdmissionClient is the client API for Admission 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 AdmissionClient interface { + Admit(ctx context.Context, in *AdmissionRequest, opts ...grpc.CallOption) (*AdmissionReply, error) +} + +type admissionClient struct { + cc grpc.ClientConnInterface +} + +func NewAdmissionClient(cc grpc.ClientConnInterface) AdmissionClient { + return &admissionClient{cc} +} + +func (c *admissionClient) Admit(ctx context.Context, in *AdmissionRequest, opts ...grpc.CallOption) (*AdmissionReply, error) { + out := new(AdmissionReply) + err := c.cc.Invoke(ctx, "/proto.Admission/Admit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AdmissionServer is the server API for Admission service. +// All implementations must embed UnimplementedAdmissionServer +// for forward compatibility +type AdmissionServer interface { + Admit(context.Context, *AdmissionRequest) (*AdmissionReply, error) + mustEmbedUnimplementedAdmissionServer() +} + +// UnimplementedAdmissionServer must be embedded to have forward compatible implementations. +type UnimplementedAdmissionServer struct { +} + +func (UnimplementedAdmissionServer) Admit(context.Context, *AdmissionRequest) (*AdmissionReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Admit not implemented") +} +func (UnimplementedAdmissionServer) mustEmbedUnimplementedAdmissionServer() {} + +// UnsafeAdmissionServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AdmissionServer will +// result in compilation errors. +type UnsafeAdmissionServer interface { + mustEmbedUnimplementedAdmissionServer() +} + +func RegisterAdmissionServer(s grpc.ServiceRegistrar, srv AdmissionServer) { + s.RegisterService(&Admission_ServiceDesc, srv) +} + +func _Admission_Admit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdmissionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdmissionServer).Admit(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Admission/Admit", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdmissionServer).Admit(ctx, req.(*AdmissionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Admission_ServiceDesc is the grpc.ServiceDesc for Admission service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Admission_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Admission", + HandlerType: (*AdmissionServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Admit", + Handler: _Admission_Admit_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "admission.proto", +} diff --git a/auth/example/main.go b/auth/example/main.go new file mode 100644 index 0000000..4d416b3 --- /dev/null +++ b/auth/example/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/auth/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedAuthenticatorServer +} + +func (s *server) Authenticate(ctx context.Context, in *proto.AuthenticateRequest) (*proto.AuthenticateReply, error) { + reply := &proto.AuthenticateReply{} + if in.GetUsername() == "gost" && in.GetPassword() == "gost" { + reply.Ok = true + } + log.Printf("auth: %s, %s, %v", in.GetUsername(), in.GetPassword(), reply.Ok) + 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.RegisterAuthenticatorServer(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/auth/proto/auth.pb.go b/auth/proto/auth.pb.go new file mode 100644 index 0000000..de7ce35 --- /dev/null +++ b/auth/proto/auth.pb.go @@ -0,0 +1,227 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// auth.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: auth.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 AuthenticateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *AuthenticateRequest) Reset() { + *x = AuthenticateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticateRequest) ProtoMessage() {} + +func (x *AuthenticateRequest) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 AuthenticateRequest.ProtoReflect.Descriptor instead. +func (*AuthenticateRequest) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{0} +} + +func (x *AuthenticateRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *AuthenticateRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type AuthenticateReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *AuthenticateReply) Reset() { + *x = AuthenticateReply{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticateReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticateReply) ProtoMessage() {} + +func (x *AuthenticateReply) ProtoReflect() protoreflect.Message { + mi := &file_auth_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 AuthenticateReply.ProtoReflect.Descriptor instead. +func (*AuthenticateReply) Descriptor() ([]byte, []int) { + return file_auth_proto_rawDescGZIP(), []int{1} +} + +func (x *AuthenticateReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +var File_auth_proto protoreflect.FileDescriptor + +var file_auth_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x4d, 0x0a, 0x13, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x32, 0x55, 0x0a, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x44, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x26, + 0x5a, 0x24, 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, 0x61, 0x75, 0x74, 0x68, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_auth_proto_rawDescOnce sync.Once + file_auth_proto_rawDescData = file_auth_proto_rawDesc +) + +func file_auth_proto_rawDescGZIP() []byte { + file_auth_proto_rawDescOnce.Do(func() { + file_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_proto_rawDescData) + }) + return file_auth_proto_rawDescData +} + +var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_auth_proto_goTypes = []interface{}{ + (*AuthenticateRequest)(nil), // 0: proto.AuthenticateRequest + (*AuthenticateReply)(nil), // 1: proto.AuthenticateReply +} +var file_auth_proto_depIdxs = []int32{ + 0, // 0: proto.Authenticator.Authenticate:input_type -> proto.AuthenticateRequest + 1, // 1: proto.Authenticator.Authenticate:output_type -> proto.AuthenticateReply + 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_auth_proto_init() } +func file_auth_proto_init() { + if File_auth_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticateReply); 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_auth_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_auth_proto_goTypes, + DependencyIndexes: file_auth_proto_depIdxs, + MessageInfos: file_auth_proto_msgTypes, + }.Build() + File_auth_proto = out.File + file_auth_proto_rawDesc = nil + file_auth_proto_goTypes = nil + file_auth_proto_depIdxs = nil +} diff --git a/auth/proto/auth.proto b/auth/proto/auth.proto new file mode 100644 index 0000000..22b476a --- /dev/null +++ b/auth/proto/auth.proto @@ -0,0 +1,20 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// auth.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/auth/proto"; + +message AuthenticateRequest { + string username = 1; + string password = 2; +} + +message AuthenticateReply { + bool ok = 1; +} + +service Authenticator { + rpc Authenticate(AuthenticateRequest) returns (AuthenticateReply); +} diff --git a/auth/proto/auth_grpc.pb.go b/auth/proto/auth_grpc.pb.go new file mode 100644 index 0000000..27a29a4 --- /dev/null +++ b/auth/proto/auth_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// AuthenticatorClient is the client API for Authenticator 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 AuthenticatorClient interface { + Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateReply, error) +} + +type authenticatorClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthenticatorClient(cc grpc.ClientConnInterface) AuthenticatorClient { + return &authenticatorClient{cc} +} + +func (c *authenticatorClient) Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateReply, error) { + out := new(AuthenticateReply) + err := c.cc.Invoke(ctx, "/proto.Authenticator/Authenticate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AuthenticatorServer is the server API for Authenticator service. +// All implementations must embed UnimplementedAuthenticatorServer +// for forward compatibility +type AuthenticatorServer interface { + Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateReply, error) + mustEmbedUnimplementedAuthenticatorServer() +} + +// UnimplementedAuthenticatorServer must be embedded to have forward compatible implementations. +type UnimplementedAuthenticatorServer struct { +} + +func (UnimplementedAuthenticatorServer) Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented") +} +func (UnimplementedAuthenticatorServer) mustEmbedUnimplementedAuthenticatorServer() {} + +// UnsafeAuthenticatorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthenticatorServer will +// result in compilation errors. +type UnsafeAuthenticatorServer interface { + mustEmbedUnimplementedAuthenticatorServer() +} + +func RegisterAuthenticatorServer(s grpc.ServiceRegistrar, srv AuthenticatorServer) { + s.RegisterService(&Authenticator_ServiceDesc, srv) +} + +func _Authenticator_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthenticateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthenticatorServer).Authenticate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Authenticator/Authenticate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthenticatorServer).Authenticate(ctx, req.(*AuthenticateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Authenticator_ServiceDesc is the grpc.ServiceDesc for Authenticator service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Authenticator_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Authenticator", + HandlerType: (*AuthenticatorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Authenticate", + Handler: _Authenticator_Authenticate_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "auth.proto", +} diff --git a/bypass/example/main.go b/bypass/example/main.go new file mode 100644 index 0000000..b6fc250 --- /dev/null +++ b/bypass/example/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/bypass/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedBypassServer +} + +func (s *server) Bypass(ctx context.Context, in *proto.BypassRequest) (*proto.BypassReply, error) { + reply := &proto.BypassReply{} + if in.GetAddr() == "example.com" { + reply.Ok = true + } + log.Printf("bypass: %s, %v", in.GetAddr(), reply.Ok) + 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.RegisterBypassServer(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/bypass/proto/bypass.pb.go b/bypass/proto/bypass.pb.go new file mode 100644 index 0000000..f791c4d --- /dev/null +++ b/bypass/proto/bypass.pb.go @@ -0,0 +1,215 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// bypass.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: bypass.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 BypassRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` +} + +func (x *BypassRequest) Reset() { + *x = BypassRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_bypass_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BypassRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BypassRequest) ProtoMessage() {} + +func (x *BypassRequest) ProtoReflect() protoreflect.Message { + mi := &file_bypass_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 BypassRequest.ProtoReflect.Descriptor instead. +func (*BypassRequest) Descriptor() ([]byte, []int) { + return file_bypass_proto_rawDescGZIP(), []int{0} +} + +func (x *BypassRequest) GetAddr() string { + if x != nil { + return x.Addr + } + return "" +} + +type BypassReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *BypassReply) Reset() { + *x = BypassReply{} + if protoimpl.UnsafeEnabled { + mi := &file_bypass_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BypassReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BypassReply) ProtoMessage() {} + +func (x *BypassReply) ProtoReflect() protoreflect.Message { + mi := &file_bypass_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 BypassReply.ProtoReflect.Descriptor instead. +func (*BypassReply) Descriptor() ([]byte, []int) { + return file_bypass_proto_rawDescGZIP(), []int{1} +} + +func (x *BypassReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +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, 0x23, 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, 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 ( + file_bypass_proto_rawDescOnce sync.Once + file_bypass_proto_rawDescData = file_bypass_proto_rawDesc +) + +func file_bypass_proto_rawDescGZIP() []byte { + file_bypass_proto_rawDescOnce.Do(func() { + file_bypass_proto_rawDescData = protoimpl.X.CompressGZIP(file_bypass_proto_rawDescData) + }) + return file_bypass_proto_rawDescData +} + +var file_bypass_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_bypass_proto_goTypes = []interface{}{ + (*BypassRequest)(nil), // 0: proto.BypassRequest + (*BypassReply)(nil), // 1: proto.BypassReply +} +var file_bypass_proto_depIdxs = []int32{ + 0, // 0: proto.Bypass.Bypass:input_type -> proto.BypassRequest + 1, // 1: proto.Bypass.Bypass:output_type -> proto.BypassReply + 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_bypass_proto_init() } +func file_bypass_proto_init() { + if File_bypass_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_bypass_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BypassRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bypass_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BypassReply); 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_bypass_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_bypass_proto_goTypes, + DependencyIndexes: file_bypass_proto_depIdxs, + MessageInfos: file_bypass_proto_msgTypes, + }.Build() + File_bypass_proto = out.File + file_bypass_proto_rawDesc = nil + file_bypass_proto_goTypes = nil + file_bypass_proto_depIdxs = nil +} diff --git a/bypass/proto/bypass.proto b/bypass/proto/bypass.proto new file mode 100644 index 0000000..283b707 --- /dev/null +++ b/bypass/proto/bypass.proto @@ -0,0 +1,19 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// bypass.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/bypass/proto"; + +message BypassRequest { + string addr = 1; +} + +message BypassReply { + bool ok = 1; +} + +service Bypass { + rpc Bypass(BypassRequest) returns (BypassReply); +} diff --git a/bypass/proto/bypass_grpc.pb.go b/bypass/proto/bypass_grpc.pb.go new file mode 100644 index 0000000..ed8d619 --- /dev/null +++ b/bypass/proto/bypass_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// BypassClient is the client API for Bypass 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 BypassClient interface { + Bypass(ctx context.Context, in *BypassRequest, opts ...grpc.CallOption) (*BypassReply, error) +} + +type bypassClient struct { + cc grpc.ClientConnInterface +} + +func NewBypassClient(cc grpc.ClientConnInterface) BypassClient { + return &bypassClient{cc} +} + +func (c *bypassClient) Bypass(ctx context.Context, in *BypassRequest, opts ...grpc.CallOption) (*BypassReply, error) { + out := new(BypassReply) + err := c.cc.Invoke(ctx, "/proto.Bypass/Bypass", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BypassServer is the server API for Bypass service. +// All implementations must embed UnimplementedBypassServer +// for forward compatibility +type BypassServer interface { + Bypass(context.Context, *BypassRequest) (*BypassReply, error) + mustEmbedUnimplementedBypassServer() +} + +// UnimplementedBypassServer must be embedded to have forward compatible implementations. +type UnimplementedBypassServer struct { +} + +func (UnimplementedBypassServer) Bypass(context.Context, *BypassRequest) (*BypassReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Bypass not implemented") +} +func (UnimplementedBypassServer) mustEmbedUnimplementedBypassServer() {} + +// UnsafeBypassServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BypassServer will +// result in compilation errors. +type UnsafeBypassServer interface { + mustEmbedUnimplementedBypassServer() +} + +func RegisterBypassServer(s grpc.ServiceRegistrar, srv BypassServer) { + s.RegisterService(&Bypass_ServiceDesc, srv) +} + +func _Bypass_Bypass_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BypassRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BypassServer).Bypass(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bypass/Bypass", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BypassServer).Bypass(ctx, req.(*BypassRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Bypass_ServiceDesc is the grpc.ServiceDesc for Bypass service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Bypass_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Bypass", + HandlerType: (*BypassServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Bypass", + Handler: _Bypass_Bypass_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "bypass.proto", +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..707fd72 --- /dev/null +++ b/go.mod @@ -0,0 +1,16 @@ +module github.com/go-gost/plugin + +go 1.20 + +require ( + google.golang.org/grpc v1.54.0 + google.golang.org/protobuf v1.30.0 +) + +require ( + github.com/golang/protobuf v1.5.2 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..50dbd4d --- /dev/null +++ b/go.sum @@ -0,0 +1,20 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/hosts/example/main.go b/hosts/example/main.go new file mode 100644 index 0000000..a2f816f --- /dev/null +++ b/hosts/example/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/hosts/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedHostMapperServer +} + +func (s *server) Lookup(ctx context.Context, in *proto.LookupRequest) (*proto.LookupReply, error) { + reply := &proto.LookupReply{} + if in.GetHost() == "localhost" { + reply.Ips = []string{"127.0.0.1"} + reply.Ok = true + } + log.Printf("hosts: %s/%s, %v", in.GetHost(), in.GetNetwork(), reply.Ok) + 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.RegisterHostMapperServer(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/hosts/proto/hosts.pb.go b/hosts/proto/hosts.pb.go new file mode 100644 index 0000000..b9673f4 --- /dev/null +++ b/hosts/proto/hosts.pb.go @@ -0,0 +1,234 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// bypass.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: hosts.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 LookupRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` + Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` +} + +func (x *LookupRequest) Reset() { + *x = LookupRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_hosts_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LookupRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupRequest) ProtoMessage() {} + +func (x *LookupRequest) ProtoReflect() protoreflect.Message { + mi := &file_hosts_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 LookupRequest.ProtoReflect.Descriptor instead. +func (*LookupRequest) Descriptor() ([]byte, []int) { + return file_hosts_proto_rawDescGZIP(), []int{0} +} + +func (x *LookupRequest) GetNetwork() string { + if x != nil { + return x.Network + } + return "" +} + +func (x *LookupRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +type LookupReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ips []string `protobuf:"bytes,1,rep,name=ips,proto3" json:"ips,omitempty"` + Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *LookupReply) Reset() { + *x = LookupReply{} + if protoimpl.UnsafeEnabled { + mi := &file_hosts_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LookupReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LookupReply) ProtoMessage() {} + +func (x *LookupReply) ProtoReflect() protoreflect.Message { + mi := &file_hosts_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 LookupReply.ProtoReflect.Descriptor instead. +func (*LookupReply) Descriptor() ([]byte, []int) { + return file_hosts_proto_rawDescGZIP(), []int{1} +} + +func (x *LookupReply) GetIps() []string { + if x != nil { + return x.Ips + } + return nil +} + +func (x *LookupReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +var File_hosts_proto protoreflect.FileDescriptor + +var file_hosts_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x0d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 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, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, + 0x6f, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x03, 0x69, 0x70, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x02, 0x6f, 0x6b, 0x32, 0x40, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, + 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x14, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x27, 0x5a, 0x25, 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, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_hosts_proto_rawDescOnce sync.Once + file_hosts_proto_rawDescData = file_hosts_proto_rawDesc +) + +func file_hosts_proto_rawDescGZIP() []byte { + file_hosts_proto_rawDescOnce.Do(func() { + file_hosts_proto_rawDescData = protoimpl.X.CompressGZIP(file_hosts_proto_rawDescData) + }) + return file_hosts_proto_rawDescData +} + +var file_hosts_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_hosts_proto_goTypes = []interface{}{ + (*LookupRequest)(nil), // 0: proto.LookupRequest + (*LookupReply)(nil), // 1: proto.LookupReply +} +var file_hosts_proto_depIdxs = []int32{ + 0, // 0: proto.HostMapper.Lookup:input_type -> proto.LookupRequest + 1, // 1: proto.HostMapper.Lookup:output_type -> proto.LookupReply + 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_hosts_proto_init() } +func file_hosts_proto_init() { + if File_hosts_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_hosts_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LookupRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hosts_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LookupReply); 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_hosts_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_hosts_proto_goTypes, + DependencyIndexes: file_hosts_proto_depIdxs, + MessageInfos: file_hosts_proto_msgTypes, + }.Build() + File_hosts_proto = out.File + file_hosts_proto_rawDesc = nil + file_hosts_proto_goTypes = nil + file_hosts_proto_depIdxs = nil +} diff --git a/hosts/proto/hosts.proto b/hosts/proto/hosts.proto new file mode 100644 index 0000000..dd7a8f5 --- /dev/null +++ b/hosts/proto/hosts.proto @@ -0,0 +1,21 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// hosts.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/hosts/proto"; + +message LookupRequest { + string network = 1; + string host = 2; +} + +message LookupReply { + repeated string ips = 1; + bool ok = 2; +} + +service HostMapper{ + rpc Lookup(LookupRequest) returns (LookupReply); +} diff --git a/hosts/proto/hosts_grpc.pb.go b/hosts/proto/hosts_grpc.pb.go new file mode 100644 index 0000000..20a1f64 --- /dev/null +++ b/hosts/proto/hosts_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// HostMapperClient is the client API for HostMapper 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 HostMapperClient interface { + Lookup(ctx context.Context, in *LookupRequest, opts ...grpc.CallOption) (*LookupReply, error) +} + +type hostMapperClient struct { + cc grpc.ClientConnInterface +} + +func NewHostMapperClient(cc grpc.ClientConnInterface) HostMapperClient { + return &hostMapperClient{cc} +} + +func (c *hostMapperClient) Lookup(ctx context.Context, in *LookupRequest, opts ...grpc.CallOption) (*LookupReply, error) { + out := new(LookupReply) + err := c.cc.Invoke(ctx, "/proto.HostMapper/Lookup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HostMapperServer is the server API for HostMapper service. +// All implementations must embed UnimplementedHostMapperServer +// for forward compatibility +type HostMapperServer interface { + Lookup(context.Context, *LookupRequest) (*LookupReply, error) + mustEmbedUnimplementedHostMapperServer() +} + +// UnimplementedHostMapperServer must be embedded to have forward compatible implementations. +type UnimplementedHostMapperServer struct { +} + +func (UnimplementedHostMapperServer) Lookup(context.Context, *LookupRequest) (*LookupReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Lookup not implemented") +} +func (UnimplementedHostMapperServer) mustEmbedUnimplementedHostMapperServer() {} + +// UnsafeHostMapperServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HostMapperServer will +// result in compilation errors. +type UnsafeHostMapperServer interface { + mustEmbedUnimplementedHostMapperServer() +} + +func RegisterHostMapperServer(s grpc.ServiceRegistrar, srv HostMapperServer) { + s.RegisterService(&HostMapper_ServiceDesc, srv) +} + +func _HostMapper_Lookup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LookupRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HostMapperServer).Lookup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.HostMapper/Lookup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HostMapperServer).Lookup(ctx, req.(*LookupRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HostMapper_ServiceDesc is the grpc.ServiceDesc for HostMapper service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HostMapper_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.HostMapper", + HandlerType: (*HostMapperServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Lookup", + Handler: _HostMapper_Lookup_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "hosts.proto", +} diff --git a/ingress/example/main.go b/ingress/example/main.go new file mode 100644 index 0000000..264df07 --- /dev/null +++ b/ingress/example/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/ingress/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedIngressServer +} + +func (s *server) Get(ctx context.Context, in *proto.GetRequest) (*proto.GetReply, error) { + reply := &proto.GetReply{} + log.Printf("ingress: %s", in.GetHost()) + 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.RegisterIngressServer(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/ingress/proto/ingress.pb.go b/ingress/proto/ingress.pb.go new file mode 100644 index 0000000..19a0e26 --- /dev/null +++ b/ingress/proto/ingress.pb.go @@ -0,0 +1,215 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// ingress.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: ingress.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 GetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` +} + +func (x *GetRequest) Reset() { + *x = GetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ingress_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRequest) ProtoMessage() {} + +func (x *GetRequest) ProtoReflect() protoreflect.Message { + mi := &file_ingress_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 GetRequest.ProtoReflect.Descriptor instead. +func (*GetRequest) Descriptor() ([]byte, []int) { + return file_ingress_proto_rawDescGZIP(), []int{0} +} + +func (x *GetRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +type GetReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` +} + +func (x *GetReply) Reset() { + *x = GetReply{} + if protoimpl.UnsafeEnabled { + mi := &file_ingress_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetReply) ProtoMessage() {} + +func (x *GetReply) ProtoReflect() protoreflect.Message { + mi := &file_ingress_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 GetReply.ProtoReflect.Descriptor instead. +func (*GetReply) Descriptor() ([]byte, []int) { + return file_ingress_proto_rawDescGZIP(), []int{1} +} + +func (x *GetReply) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +var File_ingress_proto protoreflect.FileDescriptor + +var file_ingress_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x26, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x32, 0x34, 0x0a, 0x07, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x29, 0x0a, 0x03, 0x47, + 0x65, 0x74, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x29, 0x5a, 0x27, 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, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ingress_proto_rawDescOnce sync.Once + file_ingress_proto_rawDescData = file_ingress_proto_rawDesc +) + +func file_ingress_proto_rawDescGZIP() []byte { + file_ingress_proto_rawDescOnce.Do(func() { + file_ingress_proto_rawDescData = protoimpl.X.CompressGZIP(file_ingress_proto_rawDescData) + }) + return file_ingress_proto_rawDescData +} + +var file_ingress_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_ingress_proto_goTypes = []interface{}{ + (*GetRequest)(nil), // 0: proto.GetRequest + (*GetReply)(nil), // 1: proto.GetReply +} +var file_ingress_proto_depIdxs = []int32{ + 0, // 0: proto.Ingress.Get:input_type -> proto.GetRequest + 1, // 1: proto.Ingress.Get:output_type -> proto.GetReply + 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_ingress_proto_init() } +func file_ingress_proto_init() { + if File_ingress_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ingress_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ingress_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetReply); 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_ingress_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ingress_proto_goTypes, + DependencyIndexes: file_ingress_proto_depIdxs, + MessageInfos: file_ingress_proto_msgTypes, + }.Build() + File_ingress_proto = out.File + file_ingress_proto_rawDesc = nil + file_ingress_proto_goTypes = nil + file_ingress_proto_depIdxs = nil +} diff --git a/ingress/proto/ingress.proto b/ingress/proto/ingress.proto new file mode 100644 index 0000000..9afaed9 --- /dev/null +++ b/ingress/proto/ingress.proto @@ -0,0 +1,19 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// ingress.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/ingress/proto"; + +message GetRequest { + string host = 1; +} + +message GetReply { + string endpoint = 1; +} + +service Ingress { + rpc Get(GetRequest) returns (GetReply); +} diff --git a/ingress/proto/ingress_grpc.pb.go b/ingress/proto/ingress_grpc.pb.go new file mode 100644 index 0000000..830eddc --- /dev/null +++ b/ingress/proto/ingress_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// IngressClient is the client API for Ingress 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 IngressClient interface { + Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetReply, error) +} + +type ingressClient struct { + cc grpc.ClientConnInterface +} + +func NewIngressClient(cc grpc.ClientConnInterface) IngressClient { + return &ingressClient{cc} +} + +func (c *ingressClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetReply, error) { + out := new(GetReply) + err := c.cc.Invoke(ctx, "/proto.Ingress/Get", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// IngressServer is the server API for Ingress service. +// All implementations must embed UnimplementedIngressServer +// for forward compatibility +type IngressServer interface { + Get(context.Context, *GetRequest) (*GetReply, error) + mustEmbedUnimplementedIngressServer() +} + +// UnimplementedIngressServer must be embedded to have forward compatible implementations. +type UnimplementedIngressServer struct { +} + +func (UnimplementedIngressServer) Get(context.Context, *GetRequest) (*GetReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") +} +func (UnimplementedIngressServer) mustEmbedUnimplementedIngressServer() {} + +// UnsafeIngressServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to IngressServer will +// result in compilation errors. +type UnsafeIngressServer interface { + mustEmbedUnimplementedIngressServer() +} + +func RegisterIngressServer(s grpc.ServiceRegistrar, srv IngressServer) { + s.RegisterService(&Ingress_ServiceDesc, srv) +} + +func _Ingress_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IngressServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Ingress/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IngressServer).Get(ctx, req.(*GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Ingress_ServiceDesc is the grpc.ServiceDesc for Ingress service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Ingress_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Ingress", + HandlerType: (*IngressServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Get", + Handler: _Ingress_Get_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ingress.proto", +} diff --git a/recorder/example/main.go b/recorder/example/main.go new file mode 100644 index 0000000..5134acb --- /dev/null +++ b/recorder/example/main.go @@ -0,0 +1,42 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/recorder/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedRecorderServer +} + +func (s *server) Record(ctx context.Context, in *proto.RecordRequest) (*proto.RecordReply, error) { + reply := &proto.RecordReply{ + Ok: true, + } + log.Printf("record: %s", string(in.GetData())) + 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.RegisterRecorderServer(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/recorder/proto/recorder.pb.go b/recorder/proto/recorder.pb.go new file mode 100644 index 0000000..e3a657d --- /dev/null +++ b/recorder/proto/recorder.pb.go @@ -0,0 +1,215 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// recorder.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: recorder.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 RecordRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *RecordRequest) Reset() { + *x = RecordRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_recorder_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RecordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordRequest) ProtoMessage() {} + +func (x *RecordRequest) ProtoReflect() protoreflect.Message { + mi := &file_recorder_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 RecordRequest.ProtoReflect.Descriptor instead. +func (*RecordRequest) Descriptor() ([]byte, []int) { + return file_recorder_proto_rawDescGZIP(), []int{0} +} + +func (x *RecordRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type RecordReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *RecordReply) Reset() { + *x = RecordReply{} + if protoimpl.UnsafeEnabled { + mi := &file_recorder_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RecordReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordReply) ProtoMessage() {} + +func (x *RecordReply) ProtoReflect() protoreflect.Message { + mi := &file_recorder_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 RecordReply.ProtoReflect.Descriptor instead. +func (*RecordReply) Descriptor() ([]byte, []int) { + return file_recorder_proto_rawDescGZIP(), []int{1} +} + +func (x *RecordReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +var File_recorder_proto protoreflect.FileDescriptor + +var file_recorder_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x0d, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1d, 0x0a, 0x0b, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x6f, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x32, 0x3e, 0x0a, 0x08, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x29, 0x5a, 0x27, 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, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_recorder_proto_rawDescOnce sync.Once + file_recorder_proto_rawDescData = file_recorder_proto_rawDesc +) + +func file_recorder_proto_rawDescGZIP() []byte { + file_recorder_proto_rawDescOnce.Do(func() { + file_recorder_proto_rawDescData = protoimpl.X.CompressGZIP(file_recorder_proto_rawDescData) + }) + return file_recorder_proto_rawDescData +} + +var file_recorder_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_recorder_proto_goTypes = []interface{}{ + (*RecordRequest)(nil), // 0: proto.RecordRequest + (*RecordReply)(nil), // 1: proto.RecordReply +} +var file_recorder_proto_depIdxs = []int32{ + 0, // 0: proto.Recorder.Record:input_type -> proto.RecordRequest + 1, // 1: proto.Recorder.Record:output_type -> proto.RecordReply + 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_recorder_proto_init() } +func file_recorder_proto_init() { + if File_recorder_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_recorder_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RecordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_recorder_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RecordReply); 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_recorder_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_recorder_proto_goTypes, + DependencyIndexes: file_recorder_proto_depIdxs, + MessageInfos: file_recorder_proto_msgTypes, + }.Build() + File_recorder_proto = out.File + file_recorder_proto_rawDesc = nil + file_recorder_proto_goTypes = nil + file_recorder_proto_depIdxs = nil +} diff --git a/recorder/proto/recorder.proto b/recorder/proto/recorder.proto new file mode 100644 index 0000000..02606da --- /dev/null +++ b/recorder/proto/recorder.proto @@ -0,0 +1,19 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// recorder.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/ingress/proto"; + +message RecordRequest { + bytes data = 1; +} + +message RecordReply { + bool ok = 1; +} + +service Recorder { + rpc Record(RecordRequest) returns (RecordReply); +} diff --git a/recorder/proto/recorder_grpc.pb.go b/recorder/proto/recorder_grpc.pb.go new file mode 100644 index 0000000..d261b94 --- /dev/null +++ b/recorder/proto/recorder_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// RecorderClient is the client API for Recorder 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 RecorderClient interface { + Record(ctx context.Context, in *RecordRequest, opts ...grpc.CallOption) (*RecordReply, error) +} + +type recorderClient struct { + cc grpc.ClientConnInterface +} + +func NewRecorderClient(cc grpc.ClientConnInterface) RecorderClient { + return &recorderClient{cc} +} + +func (c *recorderClient) Record(ctx context.Context, in *RecordRequest, opts ...grpc.CallOption) (*RecordReply, error) { + out := new(RecordReply) + err := c.cc.Invoke(ctx, "/proto.Recorder/Record", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RecorderServer is the server API for Recorder service. +// All implementations must embed UnimplementedRecorderServer +// for forward compatibility +type RecorderServer interface { + Record(context.Context, *RecordRequest) (*RecordReply, error) + mustEmbedUnimplementedRecorderServer() +} + +// UnimplementedRecorderServer must be embedded to have forward compatible implementations. +type UnimplementedRecorderServer struct { +} + +func (UnimplementedRecorderServer) Record(context.Context, *RecordRequest) (*RecordReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Record not implemented") +} +func (UnimplementedRecorderServer) mustEmbedUnimplementedRecorderServer() {} + +// UnsafeRecorderServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RecorderServer will +// result in compilation errors. +type UnsafeRecorderServer interface { + mustEmbedUnimplementedRecorderServer() +} + +func RegisterRecorderServer(s grpc.ServiceRegistrar, srv RecorderServer) { + s.RegisterService(&Recorder_ServiceDesc, srv) +} + +func _Recorder_Record_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RecordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecorderServer).Record(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Recorder/Record", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecorderServer).Record(ctx, req.(*RecordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Recorder_ServiceDesc is the grpc.ServiceDesc for Recorder service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Recorder_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Recorder", + HandlerType: (*RecorderServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Record", + Handler: _Recorder_Record_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "recorder.proto", +} diff --git a/resolver/example/main.go b/resolver/example/main.go new file mode 100644 index 0000000..67cddb6 --- /dev/null +++ b/resolver/example/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "github.com/go-gost/plugin/resolver/proto" + "google.golang.org/grpc" +) + +var ( + port = flag.Int("port", 8000, "The server port") +) + +type server struct { + proto.UnimplementedResolverServer +} + +func (s *server) Resolve(ctx context.Context, in *proto.ResolveRequest) (*proto.ResolveReply, error) { + reply := &proto.ResolveReply{} + if in.GetHost() == "localhost" { + reply.Ips = []string{"127.0.0.1"} + reply.Ok = true + } + log.Printf("resolver: %s/%s, %v", in.GetHost(), in.GetNetwork(), reply.Ok) + 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.RegisterResolverServer(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/resolver/proto/resolver.pb.go b/resolver/proto/resolver.pb.go new file mode 100644 index 0000000..9c336e1 --- /dev/null +++ b/resolver/proto/resolver.pb.go @@ -0,0 +1,234 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// resolver.proto + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: resolver.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 ResolveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` + Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` +} + +func (x *ResolveRequest) Reset() { + *x = ResolveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resolver_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveRequest) ProtoMessage() {} + +func (x *ResolveRequest) ProtoReflect() protoreflect.Message { + mi := &file_resolver_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 ResolveRequest.ProtoReflect.Descriptor instead. +func (*ResolveRequest) Descriptor() ([]byte, []int) { + return file_resolver_proto_rawDescGZIP(), []int{0} +} + +func (x *ResolveRequest) GetNetwork() string { + if x != nil { + return x.Network + } + return "" +} + +func (x *ResolveRequest) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +type ResolveReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ips []string `protobuf:"bytes,1,rep,name=ips,proto3" json:"ips,omitempty"` + Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"` +} + +func (x *ResolveReply) Reset() { + *x = ResolveReply{} + if protoimpl.UnsafeEnabled { + mi := &file_resolver_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveReply) ProtoMessage() {} + +func (x *ResolveReply) ProtoReflect() protoreflect.Message { + mi := &file_resolver_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 ResolveReply.ProtoReflect.Descriptor instead. +func (*ResolveReply) Descriptor() ([]byte, []int) { + return file_resolver_proto_rawDescGZIP(), []int{1} +} + +func (x *ResolveReply) GetIps() []string { + if x != nil { + return x.Ips + } + return nil +} + +func (x *ResolveReply) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +var File_resolver_proto protoreflect.FileDescriptor + +var file_resolver_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 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, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x30, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x70, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x70, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x32, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x2a, 0x5a, 0x28, + 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, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, + 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_resolver_proto_rawDescOnce sync.Once + file_resolver_proto_rawDescData = file_resolver_proto_rawDesc +) + +func file_resolver_proto_rawDescGZIP() []byte { + file_resolver_proto_rawDescOnce.Do(func() { + file_resolver_proto_rawDescData = protoimpl.X.CompressGZIP(file_resolver_proto_rawDescData) + }) + return file_resolver_proto_rawDescData +} + +var file_resolver_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_resolver_proto_goTypes = []interface{}{ + (*ResolveRequest)(nil), // 0: proto.ResolveRequest + (*ResolveReply)(nil), // 1: proto.ResolveReply +} +var file_resolver_proto_depIdxs = []int32{ + 0, // 0: proto.Resolver.Resolve:input_type -> proto.ResolveRequest + 1, // 1: proto.Resolver.Resolve:output_type -> proto.ResolveReply + 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_resolver_proto_init() } +func file_resolver_proto_init() { + if File_resolver_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_resolver_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resolver_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveReply); 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_resolver_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_resolver_proto_goTypes, + DependencyIndexes: file_resolver_proto_depIdxs, + MessageInfos: file_resolver_proto_msgTypes, + }.Build() + File_resolver_proto = out.File + file_resolver_proto_rawDesc = nil + file_resolver_proto_goTypes = nil + file_resolver_proto_depIdxs = nil +} diff --git a/resolver/proto/resolver.proto b/resolver/proto/resolver.proto new file mode 100644 index 0000000..3c4f4f0 --- /dev/null +++ b/resolver/proto/resolver.proto @@ -0,0 +1,21 @@ +// protoc --go_out=. --go_opt=paths=source_relative \ +// --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +// resolver.proto + +syntax = "proto3"; +package proto; +option go_package = "github.com/go-gost/plugin/resolver/proto"; + +message ResolveRequest { + string network = 1; + string host = 2; +} + +message ResolveReply { + repeated string ips = 1; + bool ok = 2; +} + +service Resolver{ + rpc Resolve(ResolveRequest) returns (ResolveReply); +} diff --git a/resolver/proto/resolver_grpc.pb.go b/resolver/proto/resolver_grpc.pb.go new file mode 100644 index 0000000..4f0b064 --- /dev/null +++ b/resolver/proto/resolver_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +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 + +// ResolverClient is the client API for Resolver 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 ResolverClient interface { + Resolve(ctx context.Context, in *ResolveRequest, opts ...grpc.CallOption) (*ResolveReply, error) +} + +type resolverClient struct { + cc grpc.ClientConnInterface +} + +func NewResolverClient(cc grpc.ClientConnInterface) ResolverClient { + return &resolverClient{cc} +} + +func (c *resolverClient) Resolve(ctx context.Context, in *ResolveRequest, opts ...grpc.CallOption) (*ResolveReply, error) { + out := new(ResolveReply) + err := c.cc.Invoke(ctx, "/proto.Resolver/Resolve", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ResolverServer is the server API for Resolver service. +// All implementations must embed UnimplementedResolverServer +// for forward compatibility +type ResolverServer interface { + Resolve(context.Context, *ResolveRequest) (*ResolveReply, error) + mustEmbedUnimplementedResolverServer() +} + +// UnimplementedResolverServer must be embedded to have forward compatible implementations. +type UnimplementedResolverServer struct { +} + +func (UnimplementedResolverServer) Resolve(context.Context, *ResolveRequest) (*ResolveReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Resolve not implemented") +} +func (UnimplementedResolverServer) mustEmbedUnimplementedResolverServer() {} + +// UnsafeResolverServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ResolverServer will +// result in compilation errors. +type UnsafeResolverServer interface { + mustEmbedUnimplementedResolverServer() +} + +func RegisterResolverServer(s grpc.ServiceRegistrar, srv ResolverServer) { + s.RegisterService(&Resolver_ServiceDesc, srv) +} + +func _Resolver_Resolve_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResolverServer).Resolve(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Resolver/Resolve", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResolverServer).Resolve(ctx, req.(*ResolveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Resolver_ServiceDesc is the grpc.ServiceDesc for Resolver service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Resolver_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Resolver", + HandlerType: (*ResolverServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Resolve", + Handler: _Resolver_Resolve_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "resolver.proto", +}