From b3e891ca0f59e0af6f89e1530518d30cbc41f9ec Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 22 Dec 2021 20:43:51 +0100 Subject: [PATCH] introducing gRPC for control socket IPC --- Makefile | 22 +- cmd/wicectl/main.go | 2 +- go.mod | 2 + pkg/intf/base.go | 76 +++-- pkg/intf/interfaces.go | 15 +- pkg/intf/peer.go | 41 ++- pkg/pb/common.go | 22 ++ pkg/pb/common.pb.go | 665 +++++++++++++++++++++++++++++++++++++++ pkg/pb/common.proto | 54 ++++ pkg/pb/event.go | 28 ++ pkg/pb/event.pb.go | 497 +++++++++++++++++++++++++++++ pkg/pb/event.proto | 38 +++ pkg/pb/offer.pb.go | 431 +++++++++++++++++++++++++ pkg/pb/offer.proto | 44 +++ pkg/pb/socket.pb.go | 82 +++++ pkg/pb/socket.proto | 20 ++ pkg/pb/socket_grpc.pb.go | 201 ++++++++++++ pkg/socket/client.go | 96 +++--- pkg/socket/logger.go | 52 +++ pkg/socket/server.go | 133 ++++---- pkg/socket/types.go | 42 +-- 21 files changed, 2373 insertions(+), 190 deletions(-) create mode 100644 pkg/pb/common.go create mode 100644 pkg/pb/common.pb.go create mode 100644 pkg/pb/common.proto create mode 100644 pkg/pb/event.go create mode 100644 pkg/pb/event.pb.go create mode 100644 pkg/pb/event.proto create mode 100644 pkg/pb/offer.pb.go create mode 100644 pkg/pb/offer.proto create mode 100644 pkg/pb/socket.pb.go create mode 100644 pkg/pb/socket.proto create mode 100644 pkg/pb/socket_grpc.pb.go create mode 100644 pkg/socket/logger.go diff --git a/Makefile b/Makefile index 499db034..dc3b9dfe 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,12 @@ ALL_OS := linux freebsd openbsd darwin windows BINS := $(foreach X,$(ALL_OS),$(foreach Y,$(ALL_ARCH),wice-$X-$Y)) +PROTOBUFS := pkg/pb/socket.pb.go \ + pkg/pb/offer.pb.go \ + pkg/pb/common.pb.go \ + pkg/pb/event.pb.go \ + pkg/pb/socket_grpc.pb.go + temp = $(subst -, ,$@) cmd = $(word 1, $(temp)) os = $(word 2, $(temp)) @@ -18,9 +24,21 @@ all: wice-$(OS)-$(ARCH) release: $(PLATFORMS) -$(BINS): +$(BINS): $(PROTOBUFS) GOOS=$(os) \ GOARCH=$(arch) \ go build -o 'build/$(cmd)-$(os)-$(arch)' ./cmd/$(cmd) -.PHONY: release $(PLATFORMS) +%.pb.go: %.proto + protoc \ + --proto_path=$(dir $^) \ + --go_out=$(dir $^) \ + --go_opt=paths=source_relative $^ + +%_grpc.pb.go: %.proto + protoc \ + --proto_path=$(dir $^) \ + --go-grpc_out=$(dir $^) \ + --go-grpc_opt=paths=source_relative $^ + +.PHONY: release $(PLATFORMS) proto diff --git a/cmd/wicectl/main.go b/cmd/wicectl/main.go index 4e7a7e26..7330dffa 100644 --- a/cmd/wicectl/main.go +++ b/cmd/wicectl/main.go @@ -59,7 +59,7 @@ func monitor(signals chan os.Signal) { os.Exit(0) case evt := <-sock.Events: - evt.Log(logger) + evt.Log(logger, "Event") } } } diff --git a/go.mod b/go.mod index 69b0516e..74af507d 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,8 @@ require ( require ( github.com/libp2p/go-libp2p-pubsub v0.6.0 github.com/stv0g/gont v0.2.1 + google.golang.org/grpc v1.40.0 + google.golang.org/protobuf v1.27.1 ) require ( diff --git a/pkg/intf/base.go b/pkg/intf/base.go index e4e84b47..acad847f 100644 --- a/pkg/intf/base.go +++ b/pkg/intf/base.go @@ -17,6 +17,7 @@ import ( "riasc.eu/wice/internal/wg" "riasc.eu/wice/pkg/args" "riasc.eu/wice/pkg/crypto" + "riasc.eu/wice/pkg/pb" "riasc.eu/wice/pkg/signaling" "riasc.eu/wice/pkg/socket" ) @@ -252,6 +253,7 @@ func (i *BaseInterface) SyncConfig(cfg string) error { return err } + // TODO: can we sync the config fully in Go? cmd := exec.Command("wg", "syncconf", i.Name(), cfg) output, err := cmd.CombinedOutput() if err != nil { @@ -271,11 +273,21 @@ func (i *BaseInterface) onPeerAdded(p *wgtypes.Peer) { i.peers[peer.PublicKey()] = peer - i.server.BroadcastEvent(&socket.Event{ - Type: "peer", - State: "added", - Interface: i.Name(), - Peer: peer.PublicKey(), + i.server.BroadcastEvent(&pb.Event{ + Type: "peer", + State: "added", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: i.Name(), + Peers: []*pb.Peer{ + { + PublicKey: peer.PublicKey().Bytes(), + }, + }, + }, + }, + }, }) } @@ -289,11 +301,21 @@ func (i *BaseInterface) onPeerRemoved(p *wgtypes.Peer) { i.logger.WithField("peer", peer.PublicKey).Warn("Failed to close peer") } - i.server.BroadcastEvent(&socket.Event{ - Type: "peer", - State: "removed", - Interface: i.Name(), - Peer: peer.PublicKey(), + i.server.BroadcastEvent(&pb.Event{ + Type: "peer", + State: "removed", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: i.Name(), + Peers: []*pb.Peer{ + { + PublicKey: peer.PublicKey().Bytes(), + }, + }, + }, + }, + }, }) delete(i.peers, peer.PublicKey()) @@ -307,11 +329,21 @@ func (i *BaseInterface) onPeerModified(old, new *wgtypes.Peer, modified PeerModi i.logger.Error("Failed to find modified peer") } - i.server.BroadcastEvent(&socket.Event{ - Type: "peer", - State: "modified", - Interface: i.Name(), - Peer: peer.PublicKey(), + i.server.BroadcastEvent(&pb.Event{ + Type: "peer", + State: "modified", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: i.Name(), + Peers: []*pb.Peer{ + { + PublicKey: peer.PublicKey().Bytes(), + }, + }, + }, + }, + }, }) } @@ -369,10 +401,16 @@ func NewInterface(dev *wgtypes.Device, client *wgctrl.Client, backend signaling. return BaseInterface{}, fmt.Errorf("failed to fix interface configuration: %w", err) } - server.BroadcastEvent(&socket.Event{ - Type: "interface", - State: "added", - Interface: i.Name(), + i.server.BroadcastEvent(&pb.Event{ + Type: "interface", + State: "added", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: i.Name(), + }, + }, + }, }) // We remove all peers here so that they get added by the following sync diff --git a/pkg/intf/interfaces.go b/pkg/intf/interfaces.go index 5e2c14dd..4a3f4f30 100644 --- a/pkg/intf/interfaces.go +++ b/pkg/intf/interfaces.go @@ -6,6 +6,7 @@ import ( log "github.com/sirupsen/logrus" "riasc.eu/wice/pkg/args" + "riasc.eu/wice/pkg/pb" "riasc.eu/wice/pkg/signaling" "riasc.eu/wice/pkg/socket" @@ -77,10 +78,16 @@ func (interfaces *Interfaces) SyncAll(client *wgctrl.Client, backend signaling.B log.WithError(err).Fatal("Failed to close interface") } - server.BroadcastEvent(&socket.Event{ - Type: "interface", - State: "removed", - Interface: i.Name(), + server.BroadcastEvent(&pb.Event{ + Type: "interface", + State: "removed", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: i.Name(), + }, + }, + }, }) } else { keepInterfaces = append(keepInterfaces, intf) diff --git a/pkg/intf/peer.go b/pkg/intf/peer.go index 6e9dd666..cd280ae3 100644 --- a/pkg/intf/peer.go +++ b/pkg/intf/peer.go @@ -17,6 +17,7 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "riasc.eu/wice/pkg/args" "riasc.eu/wice/pkg/crypto" + "riasc.eu/wice/pkg/pb" "riasc.eu/wice/pkg/proxy" "riasc.eu/wice/pkg/signaling" "riasc.eu/wice/pkg/socket" @@ -89,11 +90,21 @@ func (p *Peer) OnModified(new *wgtypes.Peer, modified PeerModifier) { p.logger.WithField("time", new.LastHandshakeTime).Debug("New handshake") } - p.server.BroadcastEvent(&socket.Event{ - Type: "handshake", - Time: p.LastHandshakeTime, - Interface: p.Interface.Name(), - Peer: p.PublicKey(), + p.server.BroadcastEvent(&pb.Event{ + Type: "handshake", + State: "new", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: p.Interface.Name(), + Peers: []*pb.Peer{ + { + PublicKey: p.PublicKey().Bytes(), + }, + }, + }, + }, + }, }) } @@ -121,11 +132,21 @@ func (p *Peer) onConnectionStateChange(state ice.ConnectionState) { p.logger.WithField("state", stateLower).Infof("Connection state changed") - p.server.BroadcastEvent(&socket.Event{ - Type: "state", - State: stateLower, - Interface: p.Interface.Name(), - Peer: p.PublicKey(), + p.server.BroadcastEvent(&pb.Event{ + Type: "state", + State: "changed", + Event: &pb.Event_Intf{ + Intf: &pb.InterfaceEvent{ + Interface: &pb.Interface{ + Name: p.Interface.Name(), + Peers: []*pb.Peer{ + { + PublicKey: p.PublicKey().Bytes(), + }, + }, + }, + }, + }, }) if state == ice.ConnectionStateFailed { diff --git a/pkg/pb/common.go b/pkg/pb/common.go new file mode 100644 index 00000000..2be5c5c6 --- /dev/null +++ b/pkg/pb/common.go @@ -0,0 +1,22 @@ +package pb + +import "time" + +var Ok = Error{ + Ok: true, +} + +func TimeNow() *Timestamp { + t := &Timestamp{} + t.Set(time.Now()) + return t +} + +func (t *Timestamp) Set(s time.Time) { + t.Nanos = int32(s.Nanosecond()) + t.Seconds = s.Unix() +} + +func (t *Timestamp) Time() time.Time { + return time.Unix(t.Seconds, int64(t.Nanos)) +} diff --git a/pkg/pb/common.pb.go b/pkg/pb/common.pb.go new file mode 100644 index 00000000..3c45a800 --- /dev/null +++ b/pkg/pb/common.pb.go @@ -0,0 +1,665 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.14.0 +// source: common.proto + +package pb + +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 Interface_Type int32 + +const ( + Interface_UNKNOWN Interface_Type = 0 + Interface_LINUX_KERNEL Interface_Type = 1 + Interface_OPENBSD_KERNEL Interface_Type = 2 + Interface_WINDOWS_KERNEL Interface_Type = 3 + Interface_USERSPACE Interface_Type = 4 +) + +// Enum value maps for Interface_Type. +var ( + Interface_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "LINUX_KERNEL", + 2: "OPENBSD_KERNEL", + 3: "WINDOWS_KERNEL", + 4: "USERSPACE", + } + Interface_Type_value = map[string]int32{ + "UNKNOWN": 0, + "LINUX_KERNEL": 1, + "OPENBSD_KERNEL": 2, + "WINDOWS_KERNEL": 3, + "USERSPACE": 4, + } +) + +func (x Interface_Type) Enum() *Interface_Type { + p := new(Interface_Type) + *p = x + return p +} + +func (x Interface_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Interface_Type) Descriptor() protoreflect.EnumDescriptor { + return file_common_proto_enumTypes[0].Descriptor() +} + +func (Interface_Type) Type() protoreflect.EnumType { + return &file_common_proto_enumTypes[0] +} + +func (x Interface_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Interface_Type.Descriptor instead. +func (Interface_Type) EnumDescriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{4, 0} +} + +type Void struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Void) Reset() { + *x = Void{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Void) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Void) ProtoMessage() {} + +func (x *Void) ProtoReflect() protoreflect.Message { + mi := &file_common_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 Void.ProtoReflect.Descriptor instead. +func (*Void) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +type Timestamp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (x *Timestamp) Reset() { + *x = Timestamp{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Timestamp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Timestamp) ProtoMessage() {} + +func (x *Timestamp) ProtoReflect() protoreflect.Message { + mi := &file_common_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 Timestamp.ProtoReflect.Descriptor instead. +func (*Timestamp) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{1} +} + +func (x *Timestamp) GetSeconds() int64 { + if x != nil { + return x.Seconds + } + return 0 +} + +func (x *Timestamp) GetNanos() int32 { + if x != nil { + return x.Nanos + } + return 0 +} + +type Status struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Interfaces []*Interface `protobuf:"bytes,1,rep,name=interfaces,proto3" json:"interfaces,omitempty"` +} + +func (x *Status) Reset() { + *x = Status{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[2] + 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 Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{2} +} + +func (x *Status) GetInterfaces() []*Interface { + if x != nil { + return x.Interfaces + } + return nil +} + +type Error struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *Error) Reset() { + *x = Error{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Error) ProtoMessage() {} + +func (x *Error) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[3] + 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 Error.ProtoReflect.Descriptor instead. +func (*Error) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{3} +} + +func (x *Error) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *Error) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +type Interface struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type Interface_Type `protobuf:"varint,2,opt,name=type,proto3,enum=Interface_Type" json:"type,omitempty"` + PrivateKey []byte `protobuf:"bytes,3,opt,name=private_key,json=privateKey,proto3" json:"private_key,omitempty"` + PublicKey []byte `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + ListenPort uint32 `protobuf:"varint,5,opt,name=listen_port,json=listenPort,proto3" json:"listen_port,omitempty"` + FirewallMark uint32 `protobuf:"varint,6,opt,name=firewall_mark,json=firewallMark,proto3" json:"firewall_mark,omitempty"` + Peers []*Peer `protobuf:"bytes,7,rep,name=peers,proto3" json:"peers,omitempty"` +} + +func (x *Interface) Reset() { + *x = Interface{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Interface) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Interface) ProtoMessage() {} + +func (x *Interface) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[4] + 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 Interface.ProtoReflect.Descriptor instead. +func (*Interface) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{4} +} + +func (x *Interface) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Interface) GetType() Interface_Type { + if x != nil { + return x.Type + } + return Interface_UNKNOWN +} + +func (x *Interface) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey + } + return nil +} + +func (x *Interface) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *Interface) GetListenPort() uint32 { + if x != nil { + return x.ListenPort + } + return 0 +} + +func (x *Interface) GetFirewallMark() uint32 { + if x != nil { + return x.FirewallMark + } + return 0 +} + +func (x *Interface) GetPeers() []*Peer { + if x != nil { + return x.Peers + } + return nil +} + +type Peer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + Endpoint []string `protobuf:"bytes,2,rep,name=Endpoint,proto3" json:"Endpoint,omitempty"` + PersistentKeepaliveInterval uint32 `protobuf:"varint,3,opt,name=persistent_keepalive_interval,json=persistentKeepaliveInterval,proto3" json:"persistent_keepalive_interval,omitempty"` + LastHandshake *Timestamp `protobuf:"bytes,4,opt,name=last_handshake,json=lastHandshake,proto3" json:"last_handshake,omitempty"` + TransmitBytes int64 `protobuf:"varint,5,opt,name=transmit_bytes,json=transmitBytes,proto3" json:"transmit_bytes,omitempty"` + ReceiveBytes int64 `protobuf:"varint,6,opt,name=receive_bytes,json=receiveBytes,proto3" json:"receive_bytes,omitempty"` + AllowedIps []string `protobuf:"bytes,7,rep,name=allowed_ips,json=allowedIps,proto3" json:"allowed_ips,omitempty"` + ProtocolVersion uint32 `protobuf:"varint,8,opt,name=protocol_version,json=protocolVersion,proto3" json:"protocol_version,omitempty"` +} + +func (x *Peer) Reset() { + *x = Peer{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Peer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Peer) ProtoMessage() {} + +func (x *Peer) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[5] + 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 Peer.ProtoReflect.Descriptor instead. +func (*Peer) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{5} +} + +func (x *Peer) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *Peer) GetEndpoint() []string { + if x != nil { + return x.Endpoint + } + return nil +} + +func (x *Peer) GetPersistentKeepaliveInterval() uint32 { + if x != nil { + return x.PersistentKeepaliveInterval + } + return 0 +} + +func (x *Peer) GetLastHandshake() *Timestamp { + if x != nil { + return x.LastHandshake + } + return nil +} + +func (x *Peer) GetTransmitBytes() int64 { + if x != nil { + return x.TransmitBytes + } + return 0 +} + +func (x *Peer) GetReceiveBytes() int64 { + if x != nil { + return x.ReceiveBytes + } + return 0 +} + +func (x *Peer) GetAllowedIps() []string { + if x != nil { + return x.AllowedIps + } + return nil +} + +func (x *Peer) GetProtocolVersion() uint32 { + if x != nil { + return x.ProtocolVersion + } + return 0 +} + +var File_common_proto protoreflect.FileDescriptor + +var file_common_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x06, + 0x0a, 0x04, 0x56, 0x6f, 0x69, 0x64, 0x22, 0x3b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, + 0x6e, 0x6f, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, + 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x05, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, + 0x6f, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc5, 0x02, 0x0a, 0x09, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, + 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x61, 0x72, + 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, + 0x6c, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x1b, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, + 0x72, 0x73, 0x22, 0x5c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x4e, 0x55, 0x58, + 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x50, 0x45, + 0x4e, 0x42, 0x53, 0x44, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, 0x02, 0x12, 0x12, 0x0a, + 0x0e, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, + 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x53, 0x45, 0x52, 0x53, 0x50, 0x41, 0x43, 0x45, 0x10, 0x04, + 0x22, 0xd0, 0x02, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x1d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x31, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0a, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6c, 0x61, + 0x73, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x42, 0x16, 0x5a, 0x14, 0x72, 0x69, 0x61, 0x73, 0x63, 0x2e, 0x65, 0x75, 0x2f, + 0x77, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_common_proto_rawDescOnce sync.Once + file_common_proto_rawDescData = file_common_proto_rawDesc +) + +func file_common_proto_rawDescGZIP() []byte { + file_common_proto_rawDescOnce.Do(func() { + file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData) + }) + return file_common_proto_rawDescData +} + +var file_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_common_proto_goTypes = []interface{}{ + (Interface_Type)(0), // 0: Interface.Type + (*Void)(nil), // 1: Void + (*Timestamp)(nil), // 2: Timestamp + (*Status)(nil), // 3: Status + (*Error)(nil), // 4: Error + (*Interface)(nil), // 5: Interface + (*Peer)(nil), // 6: Peer +} +var file_common_proto_depIdxs = []int32{ + 5, // 0: Status.interfaces:type_name -> Interface + 0, // 1: Interface.type:type_name -> Interface.Type + 6, // 2: Interface.peers:type_name -> Peer + 2, // 3: Peer.last_handshake:type_name -> Timestamp + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_common_proto_init() } +func file_common_proto_init() { + if File_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Void); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Timestamp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Status); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Error); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Interface); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Peer); 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_common_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_proto_goTypes, + DependencyIndexes: file_common_proto_depIdxs, + EnumInfos: file_common_proto_enumTypes, + MessageInfos: file_common_proto_msgTypes, + }.Build() + File_common_proto = out.File + file_common_proto_rawDesc = nil + file_common_proto_goTypes = nil + file_common_proto_depIdxs = nil +} diff --git a/pkg/pb/common.proto b/pkg/pb/common.proto new file mode 100644 index 00000000..3a6e23ec --- /dev/null +++ b/pkg/pb/common.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +option go_package = "riasc.eu/wice/pkg/pb"; + +message Void {} + +message Timestamp { + int64 seconds = 1; + int32 nanos = 2; +} + +message Status { + repeated Interface interfaces = 1; +} + +message Error { + bool ok = 1; + string error = 2; +} + +message Interface { + enum Type { + UNKNOWN = 0; + LINUX_KERNEL = 1; + OPENBSD_KERNEL = 2; + WINDOWS_KERNEL = 3; + USERSPACE = 4; + } + + string name = 1; + Type type = 2; + + bytes private_key = 3; + bytes public_key = 4; + + uint32 listen_port = 5; + + uint32 firewall_mark = 6; + + repeated Peer peers = 7; +} + +message Peer { + bytes public_key = 1; + + repeated string Endpoint = 2; + + uint32 persistent_keepalive_interval = 3; + Timestamp last_handshake = 4; + int64 transmit_bytes = 5; + int64 receive_bytes = 6; + repeated string allowed_ips = 7; + uint32 protocol_version = 8; +} \ No newline at end of file diff --git a/pkg/pb/event.go b/pkg/pb/event.go new file mode 100644 index 00000000..92f88395 --- /dev/null +++ b/pkg/pb/event.go @@ -0,0 +1,28 @@ +package pb + +import "github.com/sirupsen/logrus" + +func (e *Event) Log(l logrus.FieldLogger, fmt string, args ...interface{}) { + f := logrus.Fields{ + "type": e.Type, + "state": e.State, + } + + if e.Time != nil { + f["time"] = e.Time.Time() + } + + l.WithFields(f).Infof(fmt, args...) +} + +func (e *Event) Match(o *Event) bool { + if e.Type != o.Type { + return false + } + + if e.State != o.State { + return false + } + + return true +} diff --git a/pkg/pb/event.pb.go b/pkg/pb/event.pb.go new file mode 100644 index 00000000..3be55b01 --- /dev/null +++ b/pkg/pb/event.pb.go @@ -0,0 +1,497 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.14.0 +// source: event.proto + +package pb + +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 BackendEvent_Type int32 + +const ( + BackendEvent_READY BackendEvent_Type = 0 +) + +// Enum value maps for BackendEvent_Type. +var ( + BackendEvent_Type_name = map[int32]string{ + 0: "READY", + } + BackendEvent_Type_value = map[string]int32{ + "READY": 0, + } +) + +func (x BackendEvent_Type) Enum() *BackendEvent_Type { + p := new(BackendEvent_Type) + *p = x + return p +} + +func (x BackendEvent_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BackendEvent_Type) Descriptor() protoreflect.EnumDescriptor { + return file_event_proto_enumTypes[0].Descriptor() +} + +func (BackendEvent_Type) Type() protoreflect.EnumType { + return &file_event_proto_enumTypes[0] +} + +func (x BackendEvent_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BackendEvent_Type.Descriptor instead. +func (BackendEvent_Type) EnumDescriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{3, 0} +} + +type Event struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Time *Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` + // Types that are assignable to Event: + // *Event_Peer + // *Event_Intf + // *Event_Backend + Event isEvent_Event `protobuf_oneof:"event"` +} + +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_event_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 Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{0} +} + +func (x *Event) GetTime() *Timestamp { + if x != nil { + return x.Time + } + return nil +} + +func (x *Event) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Event) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (m *Event) GetEvent() isEvent_Event { + if m != nil { + return m.Event + } + return nil +} + +func (x *Event) GetPeer() *PeerEvent { + if x, ok := x.GetEvent().(*Event_Peer); ok { + return x.Peer + } + return nil +} + +func (x *Event) GetIntf() *InterfaceEvent { + if x, ok := x.GetEvent().(*Event_Intf); ok { + return x.Intf + } + return nil +} + +func (x *Event) GetBackend() *BackendEvent { + if x, ok := x.GetEvent().(*Event_Backend); ok { + return x.Backend + } + return nil +} + +type isEvent_Event interface { + isEvent_Event() +} + +type Event_Peer struct { + Peer *PeerEvent `protobuf:"bytes,10,opt,name=peer,proto3,oneof"` +} + +type Event_Intf struct { + Intf *InterfaceEvent `protobuf:"bytes,11,opt,name=intf,proto3,oneof"` +} + +type Event_Backend struct { + Backend *BackendEvent `protobuf:"bytes,12,opt,name=backend,proto3,oneof"` +} + +func (*Event_Peer) isEvent_Event() {} + +func (*Event_Intf) isEvent_Event() {} + +func (*Event_Backend) isEvent_Event() {} + +type PeerEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Peer *Peer `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"` +} + +func (x *PeerEvent) Reset() { + *x = PeerEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeerEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerEvent) ProtoMessage() {} + +func (x *PeerEvent) ProtoReflect() protoreflect.Message { + mi := &file_event_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 PeerEvent.ProtoReflect.Descriptor instead. +func (*PeerEvent) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{1} +} + +func (x *PeerEvent) GetPeer() *Peer { + if x != nil { + return x.Peer + } + return nil +} + +type InterfaceEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Interface *Interface `protobuf:"bytes,1,opt,name=interface,proto3" json:"interface,omitempty"` +} + +func (x *InterfaceEvent) Reset() { + *x = InterfaceEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InterfaceEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InterfaceEvent) ProtoMessage() {} + +func (x *InterfaceEvent) ProtoReflect() protoreflect.Message { + mi := &file_event_proto_msgTypes[2] + 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 InterfaceEvent.ProtoReflect.Descriptor instead. +func (*InterfaceEvent) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{2} +} + +func (x *InterfaceEvent) GetInterface() *Interface { + if x != nil { + return x.Interface + } + return nil +} + +type BackendEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type BackendEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=BackendEvent_Type" json:"type,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + ListenAddresses []string `protobuf:"bytes,3,rep,name=listen_addresses,json=listenAddresses,proto3" json:"listen_addresses,omitempty"` +} + +func (x *BackendEvent) Reset() { + *x = BackendEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BackendEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackendEvent) ProtoMessage() {} + +func (x *BackendEvent) ProtoReflect() protoreflect.Message { + mi := &file_event_proto_msgTypes[3] + 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 BackendEvent.ProtoReflect.Descriptor instead. +func (*BackendEvent) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{3} +} + +func (x *BackendEvent) GetType() BackendEvent_Type { + if x != nil { + return x.Type + } + return BackendEvent_READY +} + +func (x *BackendEvent) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *BackendEvent) GetListenAddresses() []string { + if x != nil { + return x.ListenAddresses + } + return nil +} + +var File_event_proto protoreflect.FileDescriptor + +var file_event_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xce, 0x01, 0x0a, 0x05, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x20, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x70, 0x65, 0x65, + 0x72, 0x12, 0x25, 0x0a, 0x04, 0x69, 0x6e, 0x74, 0x66, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x74, 0x66, 0x12, 0x29, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x26, 0x0a, 0x09, + 0x50, 0x65, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x04, 0x70, 0x65, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, + 0x70, 0x65, 0x65, 0x72, 0x22, 0x3a, 0x0a, 0x0e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x12, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x22, 0x11, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, + 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x00, 0x42, 0x16, 0x5a, 0x14, 0x72, 0x69, 0x61, 0x73, 0x63, + 0x2e, 0x65, 0x75, 0x2f, 0x77, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_event_proto_rawDescOnce sync.Once + file_event_proto_rawDescData = file_event_proto_rawDesc +) + +func file_event_proto_rawDescGZIP() []byte { + file_event_proto_rawDescOnce.Do(func() { + file_event_proto_rawDescData = protoimpl.X.CompressGZIP(file_event_proto_rawDescData) + }) + return file_event_proto_rawDescData +} + +var file_event_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_event_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_event_proto_goTypes = []interface{}{ + (BackendEvent_Type)(0), // 0: BackendEvent.Type + (*Event)(nil), // 1: Event + (*PeerEvent)(nil), // 2: PeerEvent + (*InterfaceEvent)(nil), // 3: InterfaceEvent + (*BackendEvent)(nil), // 4: BackendEvent + (*Timestamp)(nil), // 5: Timestamp + (*Peer)(nil), // 6: Peer + (*Interface)(nil), // 7: Interface +} +var file_event_proto_depIdxs = []int32{ + 5, // 0: Event.time:type_name -> Timestamp + 2, // 1: Event.peer:type_name -> PeerEvent + 3, // 2: Event.intf:type_name -> InterfaceEvent + 4, // 3: Event.backend:type_name -> BackendEvent + 6, // 4: PeerEvent.peer:type_name -> Peer + 7, // 5: InterfaceEvent.interface:type_name -> Interface + 0, // 6: BackendEvent.type:type_name -> BackendEvent.Type + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_event_proto_init() } +func file_event_proto_init() { + if File_event_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_event_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_event_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeerEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_event_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InterfaceEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_event_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BackendEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_event_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Event_Peer)(nil), + (*Event_Intf)(nil), + (*Event_Backend)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_event_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_event_proto_goTypes, + DependencyIndexes: file_event_proto_depIdxs, + EnumInfos: file_event_proto_enumTypes, + MessageInfos: file_event_proto_msgTypes, + }.Build() + File_event_proto = out.File + file_event_proto_rawDesc = nil + file_event_proto_goTypes = nil + file_event_proto_depIdxs = nil +} diff --git a/pkg/pb/event.proto b/pkg/pb/event.proto new file mode 100644 index 00000000..8e1d7c6d --- /dev/null +++ b/pkg/pb/event.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +option go_package = "riasc.eu/wice/pkg/pb"; + +import "common.proto"; + +message Event { + Timestamp time = 1; + string type = 2; + string state = 3; + + oneof event { + PeerEvent peer = 10; + InterfaceEvent intf = 11; + BackendEvent backend = 12; + } +} + +message PeerEvent { + Peer peer = 1; + + +} + +message InterfaceEvent { + Interface interface = 1; +} + +message BackendEvent { + enum Type { + READY = 0; + } + + Type type = 1; + + string id = 2; + repeated string listen_addresses = 3; +} \ No newline at end of file diff --git a/pkg/pb/offer.pb.go b/pkg/pb/offer.pb.go new file mode 100644 index 00000000..3a620def --- /dev/null +++ b/pkg/pb/offer.pb.go @@ -0,0 +1,431 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.14.0 +// source: offer.proto + +package pb + +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 Offer_Role int32 + +const ( + Offer_CONTROLLED Offer_Role = 0 + Offer_CONTROLLING Offer_Role = 1 +) + +// Enum value maps for Offer_Role. +var ( + Offer_Role_name = map[int32]string{ + 0: "CONTROLLED", + 1: "CONTROLLING", + } + Offer_Role_value = map[string]int32{ + "CONTROLLED": 0, + "CONTROLLING": 1, + } +) + +func (x Offer_Role) Enum() *Offer_Role { + p := new(Offer_Role) + *p = x + return p +} + +func (x Offer_Role) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Offer_Role) Descriptor() protoreflect.EnumDescriptor { + return file_offer_proto_enumTypes[0].Descriptor() +} + +func (Offer_Role) Type() protoreflect.EnumType { + return &file_offer_proto_enumTypes[0] +} + +func (x Offer_Role) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Offer_Role.Descriptor instead. +func (Offer_Role) EnumDescriptor() ([]byte, []int) { + return file_offer_proto_rawDescGZIP(), []int{1, 0} +} + +type Offer_Implementation int32 + +const ( + Offer_FULL Offer_Implementation = 0 + Offer_LITE Offer_Implementation = 1 +) + +// Enum value maps for Offer_Implementation. +var ( + Offer_Implementation_name = map[int32]string{ + 0: "FULL", + 1: "LITE", + } + Offer_Implementation_value = map[string]int32{ + "FULL": 0, + "LITE": 1, + } +) + +func (x Offer_Implementation) Enum() *Offer_Implementation { + p := new(Offer_Implementation) + *p = x + return p +} + +func (x Offer_Implementation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Offer_Implementation) Descriptor() protoreflect.EnumDescriptor { + return file_offer_proto_enumTypes[1].Descriptor() +} + +func (Offer_Implementation) Type() protoreflect.EnumType { + return &file_offer_proto_enumTypes[1] +} + +func (x Offer_Implementation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Offer_Implementation.Descriptor instead. +func (Offer_Implementation) EnumDescriptor() ([]byte, []int) { + return file_offer_proto_rawDescGZIP(), []int{1, 1} +} + +type SignedOffer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Offer []byte `protobuf:"bytes,1,opt,name=offer,proto3" json:"offer,omitempty"` + Sigature []byte `protobuf:"bytes,2,opt,name=sigature,proto3" json:"sigature,omitempty"` +} + +func (x *SignedOffer) Reset() { + *x = SignedOffer{} + if protoimpl.UnsafeEnabled { + mi := &file_offer_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedOffer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedOffer) ProtoMessage() {} + +func (x *SignedOffer) ProtoReflect() protoreflect.Message { + mi := &file_offer_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 SignedOffer.ProtoReflect.Descriptor instead. +func (*SignedOffer) Descriptor() ([]byte, []int) { + return file_offer_proto_rawDescGZIP(), []int{0} +} + +func (x *SignedOffer) GetOffer() []byte { + if x != nil { + return x.Offer + } + return nil +} + +func (x *SignedOffer) GetSigature() []byte { + if x != nil { + return x.Sigature + } + return nil +} + +type Offer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Epoch int64 `protobuf:"varint,2,opt,name=epoch,proto3" json:"epoch,omitempty"` + Role Offer_Role `protobuf:"varint,3,opt,name=role,proto3,enum=wice.Offer_Role" json:"role,omitempty"` + Implementation Offer_Implementation `protobuf:"varint,4,opt,name=implementation,proto3,enum=wice.Offer_Implementation" json:"implementation,omitempty"` + Candidates []*Candidate `protobuf:"bytes,5,rep,name=candidates,proto3" json:"candidates,omitempty"` + Ufrag string `protobuf:"bytes,6,opt,name=Ufrag,proto3" json:"Ufrag,omitempty"` + Pwd string `protobuf:"bytes,7,opt,name=Pwd,proto3" json:"Pwd,omitempty"` +} + +func (x *Offer) Reset() { + *x = Offer{} + if protoimpl.UnsafeEnabled { + mi := &file_offer_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Offer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Offer) ProtoMessage() {} + +func (x *Offer) ProtoReflect() protoreflect.Message { + mi := &file_offer_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 Offer.ProtoReflect.Descriptor instead. +func (*Offer) Descriptor() ([]byte, []int) { + return file_offer_proto_rawDescGZIP(), []int{1} +} + +func (x *Offer) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Offer) GetEpoch() int64 { + if x != nil { + return x.Epoch + } + return 0 +} + +func (x *Offer) GetRole() Offer_Role { + if x != nil { + return x.Role + } + return Offer_CONTROLLED +} + +func (x *Offer) GetImplementation() Offer_Implementation { + if x != nil { + return x.Implementation + } + return Offer_FULL +} + +func (x *Offer) GetCandidates() []*Candidate { + if x != nil { + return x.Candidates + } + return nil +} + +func (x *Offer) GetUfrag() string { + if x != nil { + return x.Ufrag + } + return "" +} + +func (x *Offer) GetPwd() string { + if x != nil { + return x.Pwd + } + return "" +} + +type Candidate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Candidate) Reset() { + *x = Candidate{} + if protoimpl.UnsafeEnabled { + mi := &file_offer_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Candidate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Candidate) ProtoMessage() {} + +func (x *Candidate) ProtoReflect() protoreflect.Message { + mi := &file_offer_proto_msgTypes[2] + 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 Candidate.ProtoReflect.Descriptor instead. +func (*Candidate) Descriptor() ([]byte, []int) { + return file_offer_proto_rawDescGZIP(), []int{2} +} + +var File_offer_proto protoreflect.FileDescriptor + +var file_offer_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x77, + 0x69, 0x63, 0x65, 0x22, 0x3f, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x66, 0x66, + 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x69, 0x67, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x69, 0x67, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x22, 0xc9, 0x02, 0x0a, 0x05, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x24, + 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x77, + 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, + 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x77, + 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x77, + 0x69, 0x63, 0x65, 0x2e, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x63, + 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x55, 0x66, 0x72, + 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x55, 0x66, 0x72, 0x61, 0x67, 0x12, + 0x10, 0x0a, 0x03, 0x50, 0x77, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x50, 0x77, + 0x64, 0x22, 0x27, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x22, 0x24, 0x0a, 0x0e, 0x49, 0x6d, + 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, + 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x54, 0x45, 0x10, 0x01, + 0x22, 0x0b, 0x0a, 0x09, 0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x42, 0x16, 0x5a, + 0x14, 0x72, 0x69, 0x61, 0x73, 0x63, 0x2e, 0x65, 0x75, 0x2f, 0x77, 0x69, 0x63, 0x65, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_offer_proto_rawDescOnce sync.Once + file_offer_proto_rawDescData = file_offer_proto_rawDesc +) + +func file_offer_proto_rawDescGZIP() []byte { + file_offer_proto_rawDescOnce.Do(func() { + file_offer_proto_rawDescData = protoimpl.X.CompressGZIP(file_offer_proto_rawDescData) + }) + return file_offer_proto_rawDescData +} + +var file_offer_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_offer_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_offer_proto_goTypes = []interface{}{ + (Offer_Role)(0), // 0: wice.Offer.Role + (Offer_Implementation)(0), // 1: wice.Offer.Implementation + (*SignedOffer)(nil), // 2: wice.SignedOffer + (*Offer)(nil), // 3: wice.Offer + (*Candidate)(nil), // 4: wice.Candidate +} +var file_offer_proto_depIdxs = []int32{ + 0, // 0: wice.Offer.role:type_name -> wice.Offer.Role + 1, // 1: wice.Offer.implementation:type_name -> wice.Offer.Implementation + 4, // 2: wice.Offer.candidates:type_name -> wice.Candidate + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_offer_proto_init() } +func file_offer_proto_init() { + if File_offer_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_offer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedOffer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_offer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Offer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_offer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Candidate); 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_offer_proto_rawDesc, + NumEnums: 2, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_offer_proto_goTypes, + DependencyIndexes: file_offer_proto_depIdxs, + EnumInfos: file_offer_proto_enumTypes, + MessageInfos: file_offer_proto_msgTypes, + }.Build() + File_offer_proto = out.File + file_offer_proto_rawDesc = nil + file_offer_proto_goTypes = nil + file_offer_proto_depIdxs = nil +} diff --git a/pkg/pb/offer.proto b/pkg/pb/offer.proto new file mode 100644 index 00000000..c9a18dd5 --- /dev/null +++ b/pkg/pb/offer.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; +package wice; + +option go_package = "riasc.eu/wice/pkg/pb"; + +message SignedOffer { + bytes offer = 1; + bytes sigature = 2; +} + +message Offer { + enum Role { + CONTROLLED = 0; + CONTROLLING = 1; + } + + enum Implementation { + FULL = 0; + LITE = 1; + } + + int64 version = 1; + int64 epoch = 2; + Role role = 3; + Implementation implementation = 4; + + repeated Candidate candidates = 5; + + string Ufrag = 6; + string Pwd = 7; +} + +message Candidate { + // Type string `json:"type"` + // Foundation string `json:"foundation"` + // Component int `json:"component"` + // NetworkType string `json:"network"` + // Priority int `json:"priority"` + // Address string `json:"address"` + // Port int `json:"port"` + // TCPType *string `json:"tcp_type,omitempty"` + // RelAddr *string `json:"related_address,omitempty"` + // RelPort *int `json:"related_port,omitempty"` +} \ No newline at end of file diff --git a/pkg/pb/socket.pb.go b/pkg/pb/socket.pb.go new file mode 100644 index 00000000..c469880d --- /dev/null +++ b/pkg/pb/socket.pb.go @@ -0,0 +1,82 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.14.0 +// source: socket.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +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) +) + +var File_socket_proto protoreflect.FileDescriptor + +var file_socket_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, + 0x77, 0x69, 0x63, 0x65, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, + 0x5f, 0x0a, 0x06, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x05, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x07, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x17, 0x0a, 0x06, 0x55, 0x6e, 0x57, 0x61, 0x69, 0x74, + 0x12, 0x05, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x06, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x1f, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x05, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, + 0x42, 0x16, 0x5a, 0x14, 0x72, 0x69, 0x61, 0x73, 0x63, 0x2e, 0x65, 0x75, 0x2f, 0x77, 0x69, 0x63, + 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_socket_proto_goTypes = []interface{}{ + (*Void)(nil), // 0: Void + (*Status)(nil), // 1: Status + (*Error)(nil), // 2: Error + (*Event)(nil), // 3: Event +} +var file_socket_proto_depIdxs = []int32{ + 0, // 0: wice.Socket.GetStatus:input_type -> Void + 0, // 1: wice.Socket.UnWait:input_type -> Void + 0, // 2: wice.Socket.StreamEvents:input_type -> Void + 1, // 3: wice.Socket.GetStatus:output_type -> Status + 2, // 4: wice.Socket.UnWait:output_type -> Error + 3, // 5: wice.Socket.StreamEvents:output_type -> Event + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] 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_socket_proto_init() } +func file_socket_proto_init() { + if File_socket_proto != nil { + return + } + file_common_proto_init() + file_event_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_socket_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_socket_proto_goTypes, + DependencyIndexes: file_socket_proto_depIdxs, + }.Build() + File_socket_proto = out.File + file_socket_proto_rawDesc = nil + file_socket_proto_goTypes = nil + file_socket_proto_depIdxs = nil +} diff --git a/pkg/pb/socket.proto b/pkg/pb/socket.proto new file mode 100644 index 00000000..99c524f4 --- /dev/null +++ b/pkg/pb/socket.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package wice; + +option go_package = "riasc.eu/wice/pkg/pb"; + +import "common.proto"; +import "event.proto"; + +service Socket { + rpc GetStatus(Void) returns (Status); + rpc UnWait(Void) returns (Error); + // rpc Shutdown(Void) returns (Error); + // rpc SyncConfig(Void) returns (Error); + // rpc SyncInterfaces(Void) returns (Error); + // rpc AddInterface(Interface) returns (Error); + // rpc RemoveInterface(Interface) returns (Error); + // rpc AddPeer(Peer) returns (Error); + + rpc StreamEvents(Void) returns (stream Event); +} diff --git a/pkg/pb/socket_grpc.pb.go b/pkg/pb/socket_grpc.pb.go new file mode 100644 index 00000000..8e79f1bf --- /dev/null +++ b/pkg/pb/socket_grpc.pb.go @@ -0,0 +1,201 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package pb + +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 + +// SocketClient is the client API for Socket 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 SocketClient interface { + GetStatus(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Status, error) + UnWait(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Error, error) + StreamEvents(ctx context.Context, in *Void, opts ...grpc.CallOption) (Socket_StreamEventsClient, error) +} + +type socketClient struct { + cc grpc.ClientConnInterface +} + +func NewSocketClient(cc grpc.ClientConnInterface) SocketClient { + return &socketClient{cc} +} + +func (c *socketClient) GetStatus(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Status, error) { + out := new(Status) + err := c.cc.Invoke(ctx, "/wice.Socket/GetStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *socketClient) UnWait(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Error, error) { + out := new(Error) + err := c.cc.Invoke(ctx, "/wice.Socket/UnWait", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *socketClient) StreamEvents(ctx context.Context, in *Void, opts ...grpc.CallOption) (Socket_StreamEventsClient, error) { + stream, err := c.cc.NewStream(ctx, &Socket_ServiceDesc.Streams[0], "/wice.Socket/StreamEvents", opts...) + if err != nil { + return nil, err + } + x := &socketStreamEventsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Socket_StreamEventsClient interface { + Recv() (*Event, error) + grpc.ClientStream +} + +type socketStreamEventsClient struct { + grpc.ClientStream +} + +func (x *socketStreamEventsClient) Recv() (*Event, error) { + m := new(Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SocketServer is the server API for Socket service. +// All implementations must embed UnimplementedSocketServer +// for forward compatibility +type SocketServer interface { + GetStatus(context.Context, *Void) (*Status, error) + UnWait(context.Context, *Void) (*Error, error) + StreamEvents(*Void, Socket_StreamEventsServer) error + mustEmbedUnimplementedSocketServer() +} + +// UnimplementedSocketServer must be embedded to have forward compatible implementations. +type UnimplementedSocketServer struct { +} + +func (UnimplementedSocketServer) GetStatus(context.Context, *Void) (*Status, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") +} +func (UnimplementedSocketServer) UnWait(context.Context, *Void) (*Error, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnWait not implemented") +} +func (UnimplementedSocketServer) StreamEvents(*Void, Socket_StreamEventsServer) error { + return status.Errorf(codes.Unimplemented, "method StreamEvents not implemented") +} +func (UnimplementedSocketServer) mustEmbedUnimplementedSocketServer() {} + +// UnsafeSocketServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SocketServer will +// result in compilation errors. +type UnsafeSocketServer interface { + mustEmbedUnimplementedSocketServer() +} + +func RegisterSocketServer(s grpc.ServiceRegistrar, srv SocketServer) { + s.RegisterService(&Socket_ServiceDesc, srv) +} + +func _Socket_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Void) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SocketServer).GetStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/wice.Socket/GetStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SocketServer).GetStatus(ctx, req.(*Void)) + } + return interceptor(ctx, in, info, handler) +} + +func _Socket_UnWait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Void) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SocketServer).UnWait(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/wice.Socket/UnWait", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SocketServer).UnWait(ctx, req.(*Void)) + } + return interceptor(ctx, in, info, handler) +} + +func _Socket_StreamEvents_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(Void) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(SocketServer).StreamEvents(m, &socketStreamEventsServer{stream}) +} + +type Socket_StreamEventsServer interface { + Send(*Event) error + grpc.ServerStream +} + +type socketStreamEventsServer struct { + grpc.ServerStream +} + +func (x *socketStreamEventsServer) Send(m *Event) error { + return x.ServerStream.SendMsg(m) +} + +// Socket_ServiceDesc is the grpc.ServiceDesc for Socket service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Socket_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "wice.Socket", + HandlerType: (*SocketServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetStatus", + Handler: _Socket_GetStatus_Handler, + }, + { + MethodName: "UnWait", + Handler: _Socket_UnWait_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamEvents", + Handler: _Socket_StreamEvents_Handler, + ServerStreams: true, + }, + }, + Metadata: "socket.proto", +} diff --git a/pkg/socket/client.go b/pkg/socket/client.go index 90dbb510..60e0436e 100644 --- a/pkg/socket/client.go +++ b/pkg/socket/client.go @@ -1,25 +1,25 @@ package socket import ( - "encoding/json" + "context" "fmt" "io" - "net" "os" "time" log "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "riasc.eu/wice/pkg/pb" ) type Client struct { - conn net.Conn - - encoder *json.Encoder - decoder *json.Decoder - - Events chan Event + io.Closer + pb.SocketClient + grpc *grpc.ClientConn logger *log.Entry + + Events chan *pb.Event } func waitForSocket(path string) error { @@ -48,74 +48,74 @@ func Connect(path string) (*Client, error) { return nil, fmt.Errorf("failed to wait for socket: %w", err) } - conn, err := net.Dial("unix", path) + tgt := fmt.Sprintf("unix://%s", path) + conn, err := grpc.Dial(tgt, grpc.WithInsecure()) if err != nil { return nil, err } - logger := log.WithField("logger", "socket") - client := &Client{ - conn: conn, - encoder: json.NewEncoder(conn), - decoder: json.NewDecoder(conn), - - logger: logger, - - Events: make(chan Event, 100), + SocketClient: pb.NewSocketClient(conn), + grpc: conn, + logger: log.WithField("logger", "socket"), + Events: make(chan *pb.Event, 100), } - go client.handle() + sts, err := client.UnWait(context.Background(), &pb.Void{}) + if err != nil { + return nil, fmt.Errorf("failed RPC request: %w", err) + } else if !sts.Ok { + return nil, fmt.Errorf("received RPC error: %s", sts.Error) + } + + go client.streamEvents() return client, nil } -func (c *Client) handle() { - for { - var evt Event +func (c *Client) Close() error { + close(c.Events) - if err := c.decoder.Decode(&evt); err == io.EOF { - c.logger.Info("Connection closed") - break - } else if err != nil { + return c.grpc.Close() +} + +func (c *Client) streamEvents() { + str, err := c.StreamEvents(context.Background(), &pb.Void{}) + if err != nil { + c.logger.WithError(err).Error("Failed to stream events") + } + + ok := true + for ok { + evt, err := str.Recv() + if err != nil { c.logger.WithError(err).Error("Failed to receive event") - } else { - evt.Log(c.logger) - c.Events <- evt + break } + + evt.Log(c.logger, "Received event") + c.Events <- evt } } -func (c *Client) WaitForEvent(flt Event) { +func (c *Client) WaitForEvent(flt *pb.Event) *pb.Event { for evt := range c.Events { - if flt.Type != "" && flt.Type != evt.Type { - continue + if evt.Match(flt) { + return evt } - - if flt.State != "" && flt.State != evt.State { - continue - } - - if flt.Interface != "" && flt.Interface != evt.Interface { - continue - } - - if flt.Peer.IsSet() && flt.Peer != evt.Peer { - continue - } - - return } + + return nil } func (c *Client) WaitPeerHandshake() { - c.WaitForEvent(Event{ + c.WaitForEvent(&pb.Event{ Type: "handshake", }) } func (c *Client) WaitPeerConnected() { - c.WaitForEvent(Event{ + c.WaitForEvent(&pb.Event{ Type: "state", State: "connected", }) diff --git a/pkg/socket/logger.go b/pkg/socket/logger.go new file mode 100644 index 00000000..faa32d4b --- /dev/null +++ b/pkg/socket/logger.go @@ -0,0 +1,52 @@ +package socket + +import ( + "regexp" + + "github.com/sirupsen/logrus" + "google.golang.org/grpc/grpclog" +) + +var grpcLogExpr = regexp.MustCompile(`(?m)^\[(\w+)\] (.*)$`) + +type grpcLogHook struct{} + +func (h *grpcLogHook) Fire(e *logrus.Entry) error { + if m := grpcLogExpr.FindStringSubmatch(e.Message); m != nil { + e.Data["source"] = m[1] + e.Message = m[2] + } + + return nil +} + +func (h *grpcLogHook) Levels() []logrus.Level { + return logrus.AllLevels +} + +type Logger struct { + logrus.FieldLogger + + Level int +} + +func NewLogger(lvl int) grpclog.LoggerV2 { + l := logrus.WithField("logger", "grpc") + + l.Logger.AddHook(&grpcLogHook{}) + + return &Logger{ + FieldLogger: l, + Level: lvl, + } +} + +func (l *Logger) V(lvl int) bool { + return lvl > l.Level +} + +func init() { + l := NewLogger(0) + + grpclog.SetLoggerV2(l) +} diff --git a/pkg/socket/server.go b/pkg/socket/server.go index 2f701281..2a22f71f 100644 --- a/pkg/socket/server.go +++ b/pkg/socket/server.go @@ -1,111 +1,112 @@ package socket import ( - "encoding/json" - "io" - "time" + "context" + "sync" log "github.com/sirupsen/logrus" + "google.golang.org/grpc" + + "riasc.eu/wice/pkg/pb" "net" "os" ) type Server struct { + pb.SocketServer + listener net.Listener + grpc *grpc.Server + + eventListeners map[chan *pb.Event]interface{} + eventListenersLock sync.Mutex + + waitGroup sync.WaitGroup + waitOnce sync.Once logger *log.Entry - - connections map[*Connection]*struct{} } -type Connection struct { - server *Server - logger *log.Entry - - decoder *json.Decoder - encoder *json.Encoder -} - -func Listen(path string) (*Server, error) { - // Remove old sockets - if err := os.RemoveAll(path); err != nil { - log.Fatal(err) +func Listen(network string, address string, wait bool) (*Server, error) { + // Remove old unix sockets + if network == "unix" { + if err := os.RemoveAll(address); err != nil { + log.Fatal(err) + } } - l, err := net.Listen("unix", path) + l, err := net.Listen(network, address) if err != nil { return nil, err } - logger := log.WithField("logger", "socket") - s := &Server{ - listener: l, - logger: logger, - connections: map[*Connection]*struct{}{}, + listener: l, + logger: log.WithField("logger", "socket"), + grpc: grpc.NewServer(), + eventListeners: map[chan *pb.Event]interface{}{}, } - go func() { - for { - conn, err := l.Accept() - if err != nil { - log.WithError(err).Error("Failed to accept client connection") - } + pb.RegisterSocketServer(s.grpc, s) - go s.HandleConn(conn) - } - }() + go s.grpc.Serve(l) + + s.waitGroup.Add(1) + if wait { + s.logger.Info("Wait for control socket connection") + + s.waitGroup.Wait() + } return s, nil } -func (s *Server) HandleConn(conn net.Conn) { - c := &Connection{ - server: s, - decoder: json.NewDecoder(conn), - encoder: json.NewEncoder(conn), +func (s *Server) BroadcastEvent(e *pb.Event) error { + if e.Time == nil { + e.Time = pb.TimeNow() } - s.connections[c] = nil - - logger := s.logger.WithField("conn", conn.RemoteAddr().String()) - - for { - var req Request - - if err := c.decoder.Decode(&req); err == io.EOF { - logger.Info("Connection closed") - s.connections[c] = nil - break - } else if err != nil { - log.WithError(err).Error("Failed to decode client request") - } else { - if err := c.HandleReq(&req); err != nil { - log.WithError(err).Error("Failed to handle client request") - } - } + s.eventListenersLock.Lock() + for ch := range s.eventListeners { + ch <- e } -} + s.eventListenersLock.Unlock() -func (c *Connection) HandleReq(req *Request) error { - c.logger.Info("Handling request: %s", req) + e.Log(s.logger, "Broadcasted event") return nil } -func (c *Connection) SendEvent(e *Event) error { - return c.encoder.Encode(e) +func (s *Server) GetStatus(ctx context.Context, _ *pb.Void) (*pb.Status, error) { + return &pb.Status{}, nil } -func (s *Server) BroadcastEvent(e *Event) error { - if e.Time.IsZero() { - e.Time = time.Now() - } +func (s *Server) StreamEvents(_ *pb.Void, stream pb.Socket_StreamEventsServer) error { + ch := make(chan *pb.Event, 100) - for conn := range s.connections { - conn.SendEvent(e) + s.eventListenersLock.Lock() + s.eventListeners[ch] = nil + s.eventListenersLock.Unlock() + + for evt := range ch { + stream.Send(evt) } return nil } + +func (s *Server) UnWait(context.Context, *pb.Void) (*pb.Error, error) { + var e = &pb.Error{ + Ok: false, + Error: "already unwaited", + } + + s.waitOnce.Do(func() { + s.logger.Info("Control socket un-waited") + s.waitGroup.Done() + e = &pb.Ok + }) + + return e, nil +} diff --git a/pkg/socket/types.go b/pkg/socket/types.go index 1c506d0d..a51c604e 100644 --- a/pkg/socket/types.go +++ b/pkg/socket/types.go @@ -2,52 +2,14 @@ package socket import ( "fmt" - "time" - log "github.com/sirupsen/logrus" - - "riasc.eu/wice/pkg/crypto" + "riasc.eu/wice/pkg/pb" ) -type Request struct { - Type string -} - -type Response struct { -} - type Event struct { - Type string `json:"type"` - - State string `json:"state"` - - Interface string - Peer crypto.Key - - Time time.Time `json:"time"` + pb.Event } func (e *Event) String() string { return fmt.Sprintf("type=%s", e.Type) } - -func (r *Request) String() string { - return fmt.Sprintf("type=%s", r.Type) -} - -func (e *Event) Log(logger *log.Entry) { - fields := log.Fields{ - "type": e.Type, - "state": e.State, - } - - if e.Interface != "" { - fields["intf"] = e.Interface - } - - if e.Peer.IsSet() { - fields["peer"] = e.Peer.String() - } - - logger.WithFields(fields).Infof("Received event") -}