From 6ee80b1640ccd4e2e1ac648b06f9c7da6086287d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Sun, 19 Apr 2020 20:13:31 +0200 Subject: [PATCH] Allow to change settings from the UI (1/2) We start receiving notifications from the UI, which allow us to change configurations and perform actions on the daemon. The concept of Node has also been introduced, which identifies every daemon (client) connected to the UI (server). These options has been added: - Enable/Disable firewall interception (for all nodes) - Change daemons (clients) configuration. globally or per node. - Change prompt dialog options. We have fixed some bugs along the way: - Close audit client connection gracefully. - Exclude our own connections from being intercepted. - Better handling of client connection status with the UI. We probably has also introduced some other bugs (not listed here). --- daemon/conman/connection.go | 5 +- daemon/firewall/rules.go | 56 +++- daemon/main.go | 27 +- daemon/procmon/audit/client.go | 19 +- daemon/procmon/find.go | 7 - daemon/procmon/process.go | 8 + daemon/ui/client.go | 48 +-- daemon/ui/config.go | 68 ++++ daemon/ui/notifications.go | 86 +++++ daemon/ui/protocol/ui.pb.go | 579 ++++++++++++++++++++++++--------- proto/ui.proto | 33 ++ 11 files changed, 701 insertions(+), 235 deletions(-) create mode 100644 daemon/ui/config.go create mode 100644 daemon/ui/notifications.go diff --git a/daemon/conman/connection.go b/daemon/conman/connection.go index a06c49c9..a6131ddd 100644 --- a/daemon/conman/connection.go +++ b/daemon/conman/connection.go @@ -121,7 +121,10 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection) (cr *Connection, er pid := -1 for n, inode := range inodeList { if pid = procmon.GetPIDFromINode(inode, fmt.Sprint(inode, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort)); pid == os.Getpid() { - return nil, nil + // return a Process object with our PID, to be able to exclude our own connections + // (to the UI on a local socket for example) + c.Process = procmon.NewProcess(pid, "") + return c, nil } if pid != -1 { log.Debug("[%d] PID found %d", n, pid) diff --git a/daemon/firewall/rules.go b/daemon/firewall/rules.go index b6d3d7fd..fc51aac6 100644 --- a/daemon/firewall/rules.go +++ b/daemon/firewall/rules.go @@ -7,6 +7,7 @@ import ( "time" "github.com/gustavo-iniguez-goya/opensnitch/daemon/core" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/log" ) // DropMark is the mark we place on a connection when we deny it. @@ -28,6 +29,8 @@ const ( var ( lock = sync.Mutex{} + queueNum = 0 + running = false // check that rules are loaded every 5s rulesChecker = time.NewTicker(time.Second * 20) rulesCheckerChan = make(chan bool) @@ -63,13 +66,13 @@ func RunRule(action Action, enable bool, rule []string) (err error) { // QueueDNSResponses redirects DNS responses to us, in order to keep a cache // of resolved domains. // INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass -func QueueDNSResponses(enable bool, queueNum int) (err error) { +func QueueDNSResponses(enable bool, qNum int) (err error) { return RunRule(INSERT, enable, []string{ "INPUT", "--protocol", "udp", "--sport", "53", "-j", "NFQUEUE", - "--queue-num", fmt.Sprintf("%d", queueNum), + "--queue-num", fmt.Sprintf("%d", qNum), "--queue-bypass", }) } @@ -77,8 +80,8 @@ func QueueDNSResponses(enable bool, queueNum int) (err error) { // QueueConnections inserts the firewall rule which redirects connections to us. // They are queued until the user denies/accept them, or reaches a timeout. // OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass -func QueueConnections(enable bool, queueNum int) (err error) { - regexRulesQuery, _ = regexp.Compile(fmt.Sprint(`NFQUEUE.*ctstate NEW.*NFQUEUE num `, queueNum, ` bypass`)) +func QueueConnections(enable bool, qNum int) (err error) { + regexRulesQuery, _ = regexp.Compile(fmt.Sprint(`NFQUEUE.*ctstate NEW.*NFQUEUE num `, qNum, ` bypass`)) return RunRule(ADD, enable, []string{ "OUTPUT", @@ -86,7 +89,7 @@ func QueueConnections(enable bool, queueNum int) (err error) { "-m", "conntrack", "--ctstate", "NEW", "-j", "NFQUEUE", - "--queue-num", fmt.Sprintf("%d", queueNum), + "--queue-num", fmt.Sprintf("%d", qNum), "--queue-bypass", }) } @@ -153,3 +156,46 @@ func StartCheckingRules(qNum int) { func StopCheckingRules() { rulesCheckerChan <- true } + +// IsRunning returns if the firewall rules are loaded or not. +func IsRunning() bool { + return running +} + +// Stop deletes the firewall rules, allowing network traffic. +func Stop(qNum *int) { + if running == false { + return + } + if qNum != nil { + queueNum = *qNum + } + + StopCheckingRules() + QueueDNSResponses(false, queueNum) + QueueConnections(false, queueNum) + DropMarked(false) + + running = false +} + +// Init inserts the firewall rules. +func Init(qNum *int) { + if running { + return + } + if qNum != nil { + queueNum = *qNum + } + + if err := QueueDNSResponses(true, queueNum); err != nil { + log.Fatal("Error while running DNS firewall rule: %s", err) + } else if err = QueueConnections(true, queueNum); err != nil { + log.Fatal("Error while running conntrack firewall rule: %s", err) + } else if err = DropMarked(true); err != nil { + log.Fatal("Error while running drop firewall rule: %s", err) + } + go StartCheckingRules(queueNum) + + running = true +} diff --git a/daemon/main.go b/daemon/main.go index 1570e797..d0b92468 100644 --- a/daemon/main.go +++ b/daemon/main.go @@ -128,11 +128,8 @@ func setupWorkers() { func doCleanup() { log.Info("Cleaning up ...") - firewall.StopCheckingRules() - firewall.QueueDNSResponses(false, queueNum) - firewall.QueueConnections(false, queueNum) - firewall.DropMarked(false) - + firewall.Stop(&queueNum) + log.Info("Cleaning up firewall...") procmon.End() if cpuProfile != "" { @@ -175,6 +172,11 @@ func onPacket(packet netfilter.Packet) { } return } + // accept our own connections + if con.Process.ID == os.Getpid() { + packet.SetVerdict(netfilter.NF_ACCEPT) + return + } // search a match in preloaded rules r := acceptOrDeny(&packet, con) @@ -247,6 +249,7 @@ func acceptOrDeny(packet *netfilter.Packet, con *conman.Connection) *rule.Rule { packet.SetVerdictAndMark(netfilter.NF_DROP, firewall.DropMark) } + // FIXME: this log generates too much noise log.Warning("%s %s -> %s:%d (%s)", log.Bold(log.Red("✘")), log.Bold(con.Process.Path), log.Bold(con.To()), con.DstPort, log.Red(r.Name)) } @@ -298,23 +301,15 @@ func main() { firewall.DropMarked(false) uiClient = ui.NewClient(uiSocket, stats) - if configMonMethod := uiClient.ProcMonitorMethod(); configMonMethod != "" { - procmon.MonitorMethod = configMonMethod - } + // overwrite monitor method from configuration if the user has passed + // the option via command line. if procmonMethod != "" { procmon.MonitorMethod = procmonMethod } procmon.Init() // queue is ready, run firewall rules - if err = firewall.QueueDNSResponses(true, queueNum); err != nil { - log.Fatal("Error while running DNS firewall rule: %s", err) - } else if err = firewall.QueueConnections(true, queueNum); err != nil { - log.Fatal("Error while running conntrack firewall rule: %s", err) - } else if err = firewall.DropMarked(true); err != nil { - log.Fatal("Error while running drop firewall rule: %s", err) - } - go firewall.StartCheckingRules(queueNum) + firewall.Init(&queueNum) log.Info("Running on netfilter queue #%d ...", queueNum) for true { diff --git a/daemon/procmon/audit/client.go b/daemon/procmon/audit/client.go index b98ac76a..ba835c53 100644 --- a/daemon/procmon/audit/client.go +++ b/daemon/procmon/audit/client.go @@ -84,7 +84,7 @@ var ( // EventChan is an output channel where incoming auditd events will be written. // If a client opens it. EventChan = (chan Event)(nil) - stop = false + auditConn net.Conn // TODO: we may need arm arch rule64 = []string{"exit,always", "-F", "arch=b64", "-F", fmt.Sprint("ppid!=", ourPid), "-F", fmt.Sprint("pid!=", ourPid), "-S", "socket,connect", "-k", "opensnitch"} rule32 = []string{"exit,always", "-F", "arch=b32", "-F", fmt.Sprint("ppid!=", ourPid), "-F", fmt.Sprint("pid!=", ourPid), "-S", "socketcall", "-F", "a0=1", "-k", "opensnitch"} @@ -243,13 +243,6 @@ func Reader(r io.Reader, eventChan chan<- Event) { reader := bufio.NewReader(r) for { - Lock.RLock() - if stop == true { - log.Important("audit: closing reader and exiting") - Lock.RUnlock() - break - } - Lock.RUnlock() buf, _, err := reader.ReadLine() if err != nil { if err == io.EOF { @@ -261,6 +254,7 @@ func Reader(r io.Reader, eventChan chan<- Event) { continue } log.Error("AuditReader: auditd error", err) + break } parseEvent(string(buf[0:len(buf)]), eventChan) @@ -288,9 +282,9 @@ func connect() (net.Conn, error) { // Stop stops listening for events from auditd and delete the auditd rules. func Stop() { - Lock.Lock() - stop = true - Lock.Unlock() + if auditConn != nil { + auditConn.Close() + } deleteRules() if EventChan != nil { @@ -304,7 +298,10 @@ func Start() (net.Conn, error) { if err != nil { log.Error("auditd connection error %v", err) deleteRules() + return nil, err } + auditConn = c + configureSyscalls() return c, err } diff --git a/daemon/procmon/find.go b/daemon/procmon/find.go index 5f566f8b..c88583e6 100644 --- a/daemon/procmon/find.go +++ b/daemon/procmon/find.go @@ -7,10 +7,6 @@ import ( "strconv" ) -var ( - ourPid = os.Getpid() -) - func sortPidsByTime(fdList []os.FileInfo) []os.FileInfo { sort.Slice(fdList, func(i, j int) bool { t := fdList[i].ModTime().UnixNano() @@ -99,9 +95,6 @@ func getProcPids(pidsPath string) (pidList []int) { continue } if pid, err := strconv.Atoi(f.Name()); err == nil { - if pid == ourPid { - continue - } pidList = append(pidList, []int{pid}...) } } diff --git a/daemon/procmon/process.go b/daemon/procmon/process.go index e6e99505..ef14412b 100644 --- a/daemon/procmon/process.go +++ b/daemon/procmon/process.go @@ -1,6 +1,8 @@ package procmon import ( + "time" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/log" "github.com/gustavo-iniguez-goya/opensnitch/daemon/procmon/audit" ) @@ -21,6 +23,12 @@ func NewProcess(pid int, path string) *Process { } } +func Reload() { + End() + time.Sleep(1 * time.Second) + Init() +} + func End() { if MonitorMethod == MethodAudit { audit.Stop() diff --git a/daemon/ui/client.go b/daemon/ui/client.go index 11e2d092..1fdca37b 100644 --- a/daemon/ui/client.go +++ b/daemon/ui/client.go @@ -1,9 +1,7 @@ package ui import ( - "encoding/json" "fmt" - "io/ioutil" "net" "strings" "sync" @@ -15,9 +13,8 @@ import ( "github.com/gustavo-iniguez-goya/opensnitch/daemon/statistics" "github.com/gustavo-iniguez-goya/opensnitch/daemon/ui/protocol" - "golang.org/x/net/context" - "github.com/fsnotify/fsnotify" + "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" ) @@ -36,6 +33,7 @@ type Config struct { DefaultDuration string InterceptUnknown bool ProcMonitorMethod string + LogLevel uint32 } // Client holds the connection information of a client. @@ -64,46 +62,12 @@ func NewClient(path string, stats *statistics.Statistics) *Client { c.isUnixSocket = true c.socketPath = c.socketPath[7:] } - c.loadConfiguration(false) + c.loadDiskConfiguration(false) go c.poller() return c } -func (c *Client) loadConfiguration(reload bool) { - raw, err := ioutil.ReadFile(configFile) - if err != nil { - fmt.Errorf("Error loading configuration %s: %s", configFile, err) - } - - config.Lock() - defer config.Unlock() - - err = json.Unmarshal(raw, &config) - if err != nil { - fmt.Errorf("Error parsing configuration %s: %s", configFile, err) - } - - if config.DefaultAction != "" { - clientDisconnectedRule.Action = rule.Action(config.DefaultAction) - clientErrorRule.Action = rule.Action(config.DefaultAction) - } - if config.DefaultDuration != "" { - clientDisconnectedRule.Duration = rule.Duration(config.DefaultDuration) - clientErrorRule.Duration = rule.Duration(config.DefaultDuration) - } - - if err := c.configWatcher.Add(configFile); err != nil { - log.Error("Could not watch path: %s", err) - return - } - if reload == true { - return - } - - go c.monitorConfigWorker() -} - // ProcMonitorMethod returns the monitor method configured. // If it's not present in the config file, it'll return an emptry string. func (c *Client) ProcMonitorMethod() string { @@ -155,7 +119,8 @@ func (c *Client) poller() { if err := c.connect(); err != nil { log.Warning("Error while connecting to UI service: %s", err) } - } else if c.Connected() == true { + } + if c.Connected() == true { // if the client is connected and ready, send a ping if err := c.ping(time.Now()); err != nil { log.Warning("Error while pinging UI service: %s", err) @@ -169,6 +134,7 @@ func (c *Client) poller() { func (c *Client) onStatusChange(connected bool) { if connected { log.Info("Connected to the UI service on %s", c.socketPath) + go c.Subscribe() } else { log.Error("Connection to the UI service lost.") c.client = nil @@ -272,7 +238,7 @@ func (c *Client) monitorConfigWorker() { select { case event := <-c.configWatcher.Events: if (event.Op&fsnotify.Write == fsnotify.Write) || (event.Op&fsnotify.Remove == fsnotify.Remove) { - c.loadConfiguration(true) + c.loadDiskConfiguration(true) } } } diff --git a/daemon/ui/config.go b/daemon/ui/config.go new file mode 100644 index 00000000..ca046d0f --- /dev/null +++ b/daemon/ui/config.go @@ -0,0 +1,68 @@ +package ui + +import ( + "encoding/json" + "fmt" + "io/ioutil" + + "github.com/gustavo-iniguez-goya/opensnitch/daemon/log" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/procmon" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/rule" +) + +func (c *Client) loadDiskConfiguration(reload bool) { + raw, err := ioutil.ReadFile(configFile) + if err != nil { + fmt.Errorf("Error loading disk configuration %s: %s", configFile, err) + } + + if ok := c.loadConfiguration(raw); ok { + if err := c.configWatcher.Add(configFile); err != nil { + log.Error("Could not watch path: %s", err) + return + } + } + + if reload { + return + } + + go c.monitorConfigWorker() +} + +func (c *Client) loadConfiguration(rawConfig []byte) bool { + config.Lock() + defer config.Unlock() + + if err := json.Unmarshal(rawConfig, &config); err != nil { + fmt.Errorf("Error parsing configuration %s: %s", configFile, err) + return false + } + + if config.DefaultAction != "" { + clientDisconnectedRule.Action = rule.Action(config.DefaultAction) + clientErrorRule.Action = rule.Action(config.DefaultAction) + } + if config.DefaultDuration != "" { + clientDisconnectedRule.Duration = rule.Duration(config.DefaultDuration) + clientErrorRule.Duration = rule.Duration(config.DefaultDuration) + } + log.MinLevel = int(config.LogLevel) + if config.ProcMonitorMethod != "" { + procmon.MonitorMethod = config.ProcMonitorMethod + } + + return true +} + +func (c *Client) saveConfiguration(rawConfig string) { + conf, err := json.Marshal([]byte(rawConfig)) + if err != nil { + log.Error("saving json configuration: ", err, conf) + return + } + if err = ioutil.WriteFile(configFile, []byte(rawConfig), 0644); err != nil { + log.Error("writing configuration to disk: ", err) + } + return +} diff --git a/daemon/ui/notifications.go b/daemon/ui/notifications.go new file mode 100644 index 00000000..4f0fb24a --- /dev/null +++ b/daemon/ui/notifications.go @@ -0,0 +1,86 @@ +package ui + +import ( + "io" + "io/ioutil" + "strings" + "time" + + "github.com/gustavo-iniguez-goya/opensnitch/daemon/firewall" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/log" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/procmon" + "github.com/gustavo-iniguez-goya/opensnitch/daemon/ui/protocol" + "golang.org/x/net/context" +) + +func (c *Client) getClientConfig() *protocol.ClientConfig { + raw, _ := ioutil.ReadFile(configFile) + nodeName, _ := ioutil.ReadFile("/proc/sys/kernel/hostname") + nodeVersion, _ := ioutil.ReadFile("/proc/sys/kernel/version") + var ts time.Time + return &protocol.ClientConfig{ + Id: uint64(ts.UnixNano()), + Name: strings.Replace(string(nodeName), "\n", "", -1), + Version: strings.Replace(string(nodeVersion), "\n", "", -1), + IsFirewallRunning: firewall.IsRunning(), + Config: strings.Replace(string(raw), "\n", "", -1), + LogLevel: uint32(log.MinLevel), + // TODO + Rules: nil, + } +} + +func (c *Client) handleNotification(notification *protocol.Notification) { + switch { + case notification.Type == protocol.Action_CHANGE_CONFIG: + log.Info("[notification] Reloading configuration") + // this save operation triggers a re-loadConfiguration() + c.saveConfiguration(notification.Data) + // XXX: can the Reload() happen before finishing loading conf? + procmon.Reload() + case notification.Type == protocol.Action_LOAD_FIREWALL: + log.Info("[notification] starting firewall") + firewall.Init(nil) + case notification.Type == protocol.Action_UNLOAD_FIREWALL: + log.Info("[notification] stopping firewall") + firewall.Stop(nil) + } +} + +// Subscribe opens a connection with the server (UI), to start +// receiving notifications. +// It firstly sends the daemon status and configuration. +func (c *Client) Subscribe() { + log.Info("Subscribe") + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + notisStream, err := c.client.Notifications(ctx) + if err != nil { + log.Error("establishing notifications channel", err) + return + } + if err := notisStream.Send(c.getClientConfig()); err != nil { + log.Error("sending notfication HELLO", err) + return + } + log.Info("Start receiving notifications") + for { + noti, err := notisStream.Recv() + if err == io.EOF { + log.Warning("notification channel closed by the server") + break + } + if err != nil { + log.Error("getting notifications: ", err, noti) + break + } + c.handleNotification(noti) + //if err := notisStream.Send(c.getNotificationConfig()); err != nil { + // log.Error("Error Subscribe()2 sending initial packet") + //} + } + + notisStream.CloseSend() + log.Info("Stop receiving notifications") +} diff --git a/daemon/ui/protocol/ui.pb.go b/daemon/ui/protocol/ui.pb.go index f632e13b..2573863d 100644 --- a/daemon/ui/protocol/ui.pb.go +++ b/daemon/ui/protocol/ui.pb.go @@ -1,30 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: ui.proto -/* -Package protocol is a generated protocol buffer package. - -It is generated from these files: - ui.proto - -It has these top-level messages: - Event - Statistics - PingRequest - PingReply - Connection - Operator - Rule -*/ package protocol -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -38,16 +24,61 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package -type Event struct { - Time string `protobuf:"bytes,1,opt,name=time" json:"time,omitempty"` - Connection *Connection `protobuf:"bytes,2,opt,name=connection" json:"connection,omitempty"` - Rule *Rule `protobuf:"bytes,3,opt,name=rule" json:"rule,omitempty"` +type Action int32 + +const ( + Action_NONE Action = 0 + Action_LOAD_FIREWALL Action = 1 + Action_UNLOAD_FIREWALL Action = 2 + Action_CHANGE_CONFIG Action = 3 + Action_ENABLE_RULE Action = 4 + Action_DISABLE_RULE Action = 5 + Action_LOG_LEVEL Action = 6 + Action_STOP Action = 7 +) + +var Action_name = map[int32]string{ + 0: "NONE", + 1: "LOAD_FIREWALL", + 2: "UNLOAD_FIREWALL", + 3: "CHANGE_CONFIG", + 4: "ENABLE_RULE", + 5: "DISABLE_RULE", + 6: "LOG_LEVEL", + 7: "STOP", } -func (m *Event) Reset() { *m = Event{} } -func (m *Event) String() string { return proto.CompactTextString(m) } -func (*Event) ProtoMessage() {} -func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +var Action_value = map[string]int32{ + "NONE": 0, + "LOAD_FIREWALL": 1, + "UNLOAD_FIREWALL": 2, + "CHANGE_CONFIG": 3, + "ENABLE_RULE": 4, + "DISABLE_RULE": 5, + "LOG_LEVEL": 6, + "STOP": 7, +} + +func (x Action) String() string { + return proto.EnumName(Action_name, int32(x)) +} + +func (Action) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{0} +} + +type Event struct { + Time string `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + Connection *Connection `protobuf:"bytes,2,opt,name=connection,proto3" json:"connection,omitempty"` + Rule *Rule `protobuf:"bytes,3,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{0} +} func (m *Event) GetTime() string { if m != nil { @@ -71,29 +102,31 @@ func (m *Event) GetRule() *Rule { } type Statistics struct { - DaemonVersion string `protobuf:"bytes,1,opt,name=daemon_version,json=daemonVersion" json:"daemon_version,omitempty"` - Rules uint64 `protobuf:"varint,2,opt,name=rules" json:"rules,omitempty"` - Uptime uint64 `protobuf:"varint,3,opt,name=uptime" json:"uptime,omitempty"` - DnsResponses uint64 `protobuf:"varint,4,opt,name=dns_responses,json=dnsResponses" json:"dns_responses,omitempty"` - Connections uint64 `protobuf:"varint,5,opt,name=connections" json:"connections,omitempty"` - Ignored uint64 `protobuf:"varint,6,opt,name=ignored" json:"ignored,omitempty"` - Accepted uint64 `protobuf:"varint,7,opt,name=accepted" json:"accepted,omitempty"` - Dropped uint64 `protobuf:"varint,8,opt,name=dropped" json:"dropped,omitempty"` - RuleHits uint64 `protobuf:"varint,9,opt,name=rule_hits,json=ruleHits" json:"rule_hits,omitempty"` - RuleMisses uint64 `protobuf:"varint,10,opt,name=rule_misses,json=ruleMisses" json:"rule_misses,omitempty"` - ByProto map[string]uint64 `protobuf:"bytes,11,rep,name=by_proto,json=byProto" json:"by_proto,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ByAddress map[string]uint64 `protobuf:"bytes,12,rep,name=by_address,json=byAddress" json:"by_address,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ByHost map[string]uint64 `protobuf:"bytes,13,rep,name=by_host,json=byHost" json:"by_host,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ByPort map[string]uint64 `protobuf:"bytes,14,rep,name=by_port,json=byPort" json:"by_port,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ByUid map[string]uint64 `protobuf:"bytes,15,rep,name=by_uid,json=byUid" json:"by_uid,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ByExecutable map[string]uint64 `protobuf:"bytes,16,rep,name=by_executable,json=byExecutable" json:"by_executable,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - Events []*Event `protobuf:"bytes,17,rep,name=events" json:"events,omitempty"` + DaemonVersion string `protobuf:"bytes,1,opt,name=daemon_version,json=daemonVersion,proto3" json:"daemon_version,omitempty"` + Rules uint64 `protobuf:"varint,2,opt,name=rules,proto3" json:"rules,omitempty"` + Uptime uint64 `protobuf:"varint,3,opt,name=uptime,proto3" json:"uptime,omitempty"` + DnsResponses uint64 `protobuf:"varint,4,opt,name=dns_responses,json=dnsResponses,proto3" json:"dns_responses,omitempty"` + Connections uint64 `protobuf:"varint,5,opt,name=connections,proto3" json:"connections,omitempty"` + Ignored uint64 `protobuf:"varint,6,opt,name=ignored,proto3" json:"ignored,omitempty"` + Accepted uint64 `protobuf:"varint,7,opt,name=accepted,proto3" json:"accepted,omitempty"` + Dropped uint64 `protobuf:"varint,8,opt,name=dropped,proto3" json:"dropped,omitempty"` + RuleHits uint64 `protobuf:"varint,9,opt,name=rule_hits,json=ruleHits,proto3" json:"rule_hits,omitempty"` + RuleMisses uint64 `protobuf:"varint,10,opt,name=rule_misses,json=ruleMisses,proto3" json:"rule_misses,omitempty"` + ByProto map[string]uint64 `protobuf:"bytes,11,rep,name=by_proto,json=byProto,proto3" json:"by_proto,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ByAddress map[string]uint64 `protobuf:"bytes,12,rep,name=by_address,json=byAddress,proto3" json:"by_address,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ByHost map[string]uint64 `protobuf:"bytes,13,rep,name=by_host,json=byHost,proto3" json:"by_host,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ByPort map[string]uint64 `protobuf:"bytes,14,rep,name=by_port,json=byPort,proto3" json:"by_port,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ByUid map[string]uint64 `protobuf:"bytes,15,rep,name=by_uid,json=byUid,proto3" json:"by_uid,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ByExecutable map[string]uint64 `protobuf:"bytes,16,rep,name=by_executable,json=byExecutable,proto3" json:"by_executable,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Events []*Event `protobuf:"bytes,17,rep,name=events,proto3" json:"events,omitempty"` } -func (m *Statistics) Reset() { *m = Statistics{} } -func (m *Statistics) String() string { return proto.CompactTextString(m) } -func (*Statistics) ProtoMessage() {} -func (*Statistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (m *Statistics) Reset() { *m = Statistics{} } +func (m *Statistics) String() string { return proto.CompactTextString(m) } +func (*Statistics) ProtoMessage() {} +func (*Statistics) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{1} +} func (m *Statistics) GetDaemonVersion() string { if m != nil { @@ -215,14 +248,16 @@ func (m *Statistics) GetEvents() []*Event { } type PingRequest struct { - Id uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Stats *Statistics `protobuf:"bytes,2,opt,name=stats" json:"stats,omitempty"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Stats *Statistics `protobuf:"bytes,2,opt,name=stats,proto3" json:"stats,omitempty"` } -func (m *PingRequest) Reset() { *m = PingRequest{} } -func (m *PingRequest) String() string { return proto.CompactTextString(m) } -func (*PingRequest) ProtoMessage() {} -func (*PingRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (m *PingRequest) Reset() { *m = PingRequest{} } +func (m *PingRequest) String() string { return proto.CompactTextString(m) } +func (*PingRequest) ProtoMessage() {} +func (*PingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{2} +} func (m *PingRequest) GetId() uint64 { if m != nil { @@ -239,13 +274,15 @@ func (m *PingRequest) GetStats() *Statistics { } type PingReply struct { - Id uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` } -func (m *PingReply) Reset() { *m = PingReply{} } -func (m *PingReply) String() string { return proto.CompactTextString(m) } -func (*PingReply) ProtoMessage() {} -func (*PingReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +func (m *PingReply) Reset() { *m = PingReply{} } +func (m *PingReply) String() string { return proto.CompactTextString(m) } +func (*PingReply) ProtoMessage() {} +func (*PingReply) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{3} +} func (m *PingReply) GetId() uint64 { if m != nil { @@ -255,22 +292,24 @@ func (m *PingReply) GetId() uint64 { } type Connection struct { - Protocol string `protobuf:"bytes,1,opt,name=protocol" json:"protocol,omitempty"` - SrcIp string `protobuf:"bytes,2,opt,name=src_ip,json=srcIp" json:"src_ip,omitempty"` - SrcPort uint32 `protobuf:"varint,3,opt,name=src_port,json=srcPort" json:"src_port,omitempty"` - DstIp string `protobuf:"bytes,4,opt,name=dst_ip,json=dstIp" json:"dst_ip,omitempty"` - DstHost string `protobuf:"bytes,5,opt,name=dst_host,json=dstHost" json:"dst_host,omitempty"` - DstPort uint32 `protobuf:"varint,6,opt,name=dst_port,json=dstPort" json:"dst_port,omitempty"` - UserId uint32 `protobuf:"varint,7,opt,name=user_id,json=userId" json:"user_id,omitempty"` - ProcessId uint32 `protobuf:"varint,8,opt,name=process_id,json=processId" json:"process_id,omitempty"` - ProcessPath string `protobuf:"bytes,9,opt,name=process_path,json=processPath" json:"process_path,omitempty"` - ProcessArgs []string `protobuf:"bytes,10,rep,name=process_args,json=processArgs" json:"process_args,omitempty"` + Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` + SrcIp string `protobuf:"bytes,2,opt,name=src_ip,json=srcIp,proto3" json:"src_ip,omitempty"` + SrcPort uint32 `protobuf:"varint,3,opt,name=src_port,json=srcPort,proto3" json:"src_port,omitempty"` + DstIp string `protobuf:"bytes,4,opt,name=dst_ip,json=dstIp,proto3" json:"dst_ip,omitempty"` + DstHost string `protobuf:"bytes,5,opt,name=dst_host,json=dstHost,proto3" json:"dst_host,omitempty"` + DstPort uint32 `protobuf:"varint,6,opt,name=dst_port,json=dstPort,proto3" json:"dst_port,omitempty"` + UserId uint32 `protobuf:"varint,7,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ProcessId uint32 `protobuf:"varint,8,opt,name=process_id,json=processId,proto3" json:"process_id,omitempty"` + ProcessPath string `protobuf:"bytes,9,opt,name=process_path,json=processPath,proto3" json:"process_path,omitempty"` + ProcessArgs []string `protobuf:"bytes,10,rep,name=process_args,json=processArgs,proto3" json:"process_args,omitempty"` } -func (m *Connection) Reset() { *m = Connection{} } -func (m *Connection) String() string { return proto.CompactTextString(m) } -func (*Connection) ProtoMessage() {} -func (*Connection) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (m *Connection) Reset() { *m = Connection{} } +func (m *Connection) String() string { return proto.CompactTextString(m) } +func (*Connection) ProtoMessage() {} +func (*Connection) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{4} +} func (m *Connection) GetProtocol() string { if m != nil { @@ -343,15 +382,17 @@ func (m *Connection) GetProcessArgs() []string { } type Operator struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Operand string `protobuf:"bytes,2,opt,name=operand" json:"operand,omitempty"` - Data string `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Operand string `protobuf:"bytes,2,opt,name=operand,proto3" json:"operand,omitempty"` + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` } -func (m *Operator) Reset() { *m = Operator{} } -func (m *Operator) String() string { return proto.CompactTextString(m) } -func (*Operator) ProtoMessage() {} -func (*Operator) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } +func (m *Operator) Reset() { *m = Operator{} } +func (m *Operator) String() string { return proto.CompactTextString(m) } +func (*Operator) ProtoMessage() {} +func (*Operator) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{5} +} func (m *Operator) GetType() string { if m != nil { @@ -375,16 +416,18 @@ func (m *Operator) GetData() string { } type Rule struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Action string `protobuf:"bytes,2,opt,name=action" json:"action,omitempty"` - Duration string `protobuf:"bytes,3,opt,name=duration" json:"duration,omitempty"` - Operator *Operator `protobuf:"bytes,4,opt,name=operator" json:"operator,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + Duration string `protobuf:"bytes,3,opt,name=duration,proto3" json:"duration,omitempty"` + Operator *Operator `protobuf:"bytes,4,opt,name=operator,proto3" json:"operator,omitempty"` } -func (m *Rule) Reset() { *m = Rule{} } -func (m *Rule) String() string { return proto.CompactTextString(m) } -func (*Rule) ProtoMessage() {} -func (*Rule) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } +func (m *Rule) Reset() { *m = Rule{} } +func (m *Rule) String() string { return proto.CompactTextString(m) } +func (*Rule) ProtoMessage() {} +func (*Rule) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{6} +} func (m *Rule) GetName() string { if m != nil { @@ -414,7 +457,134 @@ func (m *Rule) GetOperator() *Operator { return nil } +type ClientConfig struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + IsFirewallRunning bool `protobuf:"varint,4,opt,name=isFirewallRunning,proto3" json:"isFirewallRunning,omitempty"` + // json string + Config string `protobuf:"bytes,5,opt,name=config,proto3" json:"config,omitempty"` + LogLevel uint32 `protobuf:"varint,6,opt,name=logLevel,proto3" json:"logLevel,omitempty"` + Rules []*Rule `protobuf:"bytes,7,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (m *ClientConfig) Reset() { *m = ClientConfig{} } +func (m *ClientConfig) String() string { return proto.CompactTextString(m) } +func (*ClientConfig) ProtoMessage() {} +func (*ClientConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{7} +} + +func (m *ClientConfig) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *ClientConfig) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ClientConfig) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *ClientConfig) GetIsFirewallRunning() bool { + if m != nil { + return m.IsFirewallRunning + } + return false +} + +func (m *ClientConfig) GetConfig() string { + if m != nil { + return m.Config + } + return "" +} + +func (m *ClientConfig) GetLogLevel() uint32 { + if m != nil { + return m.LogLevel + } + return 0 +} + +func (m *ClientConfig) GetRules() []*Rule { + if m != nil { + return m.Rules + } + return nil +} + +type Notification struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ClientName string `protobuf:"bytes,2,opt,name=clientName,proto3" json:"clientName,omitempty"` + ServerName string `protobuf:"bytes,3,opt,name=serverName,proto3" json:"serverName,omitempty"` + // CHANGE_CONFIG: 2, data: {"default_timeout": 1, ...} + Type Action `protobuf:"varint,4,opt,name=type,proto3,enum=protocol.Action" json:"type,omitempty"` + Data string `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + Rules []*Rule `protobuf:"bytes,6,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (m *Notification) Reset() { *m = Notification{} } +func (m *Notification) String() string { return proto.CompactTextString(m) } +func (*Notification) ProtoMessage() {} +func (*Notification) Descriptor() ([]byte, []int) { + return fileDescriptor_63867a62624c1283, []int{8} +} + +func (m *Notification) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Notification) GetClientName() string { + if m != nil { + return m.ClientName + } + return "" +} + +func (m *Notification) GetServerName() string { + if m != nil { + return m.ServerName + } + return "" +} + +func (m *Notification) GetType() Action { + if m != nil { + return m.Type + } + return Action_NONE +} + +func (m *Notification) GetData() string { + if m != nil { + return m.Data + } + return "" +} + +func (m *Notification) GetRules() []*Rule { + if m != nil { + return m.Rules + } + return nil +} + func init() { + proto.RegisterEnum("protocol.Action", Action_name, Action_value) proto.RegisterType((*Event)(nil), "protocol.Event") proto.RegisterType((*Statistics)(nil), "protocol.Statistics") proto.RegisterType((*PingRequest)(nil), "protocol.PingRequest") @@ -422,6 +592,86 @@ func init() { proto.RegisterType((*Connection)(nil), "protocol.Connection") proto.RegisterType((*Operator)(nil), "protocol.Operator") proto.RegisterType((*Rule)(nil), "protocol.Rule") + proto.RegisterType((*ClientConfig)(nil), "protocol.ClientConfig") + proto.RegisterType((*Notification)(nil), "protocol.Notification") +} + +func init() { + proto.RegisterFile("ui.proto", fileDescriptor_63867a62624c1283) +} + +var fileDescriptor_63867a62624c1283 = []byte{ + // 1120 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdb, 0x6e, 0xdb, 0x46, + 0x13, 0xb6, 0x4e, 0x14, 0x35, 0x3a, 0x58, 0xde, 0xc4, 0xf9, 0xf9, 0x2b, 0x68, 0xe3, 0x30, 0x69, + 0x6b, 0x04, 0x85, 0xd1, 0xba, 0x41, 0x91, 0x04, 0x01, 0x0a, 0xd9, 0xa1, 0x6d, 0xa1, 0xaa, 0x64, + 0xd0, 0x75, 0x7a, 0x49, 0xf0, 0xb0, 0x91, 0x89, 0xd0, 0x24, 0xbb, 0xbb, 0x74, 0xcb, 0x9b, 0xde, + 0xf7, 0x41, 0xfa, 0x06, 0xbd, 0xee, 0x6d, 0x5f, 0xa0, 0x0f, 0x54, 0xec, 0x2c, 0x29, 0x32, 0x76, + 0x1d, 0xc0, 0x57, 0xe2, 0x7c, 0xdf, 0x7c, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0x02, 0x3d, 0x0b, 0xf7, + 0x52, 0x96, 0x88, 0x84, 0xe8, 0xf8, 0xe3, 0x27, 0x91, 0x99, 0x41, 0xc7, 0xba, 0xa2, 0xb1, 0x20, + 0x04, 0xda, 0x22, 0xbc, 0xa4, 0x46, 0x63, 0xa7, 0xb1, 0xdb, 0xb3, 0xf1, 0x9b, 0x3c, 0x07, 0xf0, + 0x93, 0x38, 0xa6, 0xbe, 0x08, 0x93, 0xd8, 0x68, 0xee, 0x34, 0x76, 0xfb, 0xfb, 0xf7, 0xf7, 0x4a, + 0xed, 0xde, 0xe1, 0x9a, 0xb3, 0x6b, 0x7e, 0xc4, 0x84, 0x36, 0xcb, 0x22, 0x6a, 0xb4, 0xd0, 0x7f, + 0x54, 0xf9, 0xdb, 0x59, 0x44, 0x6d, 0xe4, 0xcc, 0xbf, 0x75, 0x80, 0x33, 0xe1, 0x8a, 0x90, 0x8b, + 0xd0, 0xe7, 0xe4, 0x33, 0x18, 0x05, 0x2e, 0xbd, 0x4c, 0x62, 0xe7, 0x8a, 0x32, 0x2e, 0x17, 0x53, + 0x69, 0x0c, 0x15, 0xfa, 0x56, 0x81, 0xe4, 0x3e, 0x74, 0xa4, 0x9a, 0x63, 0x2a, 0x6d, 0x5b, 0x19, + 0xe4, 0x01, 0x68, 0x59, 0x8a, 0xb9, 0xb7, 0x10, 0x2e, 0x2c, 0xf2, 0x04, 0x86, 0x41, 0xcc, 0x1d, + 0x46, 0x79, 0x9a, 0xc4, 0x9c, 0x72, 0xa3, 0x8d, 0xf4, 0x20, 0x88, 0xb9, 0x5d, 0x62, 0x64, 0x07, + 0xfa, 0x55, 0xea, 0xdc, 0xe8, 0xa0, 0x4b, 0x1d, 0x22, 0x06, 0x74, 0xc3, 0x55, 0x9c, 0x30, 0x1a, + 0x18, 0x1a, 0xb2, 0xa5, 0x49, 0x26, 0xa0, 0xbb, 0xbe, 0x4f, 0x53, 0x41, 0x03, 0xa3, 0x8b, 0xd4, + 0xda, 0x96, 0xaa, 0x80, 0x25, 0x69, 0x4a, 0x03, 0x43, 0x57, 0xaa, 0xc2, 0x24, 0x0f, 0xa1, 0x27, + 0xf3, 0x76, 0x2e, 0x42, 0xc1, 0x8d, 0x9e, 0x92, 0x49, 0xe0, 0x24, 0x14, 0x9c, 0x3c, 0x82, 0x3e, + 0x92, 0x97, 0x21, 0x97, 0x19, 0x03, 0xd2, 0x20, 0xa1, 0x1f, 0x10, 0x21, 0xaf, 0x41, 0xf7, 0x72, + 0x07, 0x4b, 0x6a, 0xf4, 0x77, 0x5a, 0xbb, 0xfd, 0xfd, 0xc7, 0x55, 0x81, 0xab, 0x8a, 0xee, 0x1d, + 0xe4, 0xa7, 0x12, 0xb5, 0x62, 0xc1, 0x72, 0xbb, 0xeb, 0x29, 0x8b, 0x1c, 0x00, 0x78, 0xb9, 0xe3, + 0x06, 0x01, 0xa3, 0x9c, 0x1b, 0x03, 0xd4, 0x3f, 0xb9, 0x45, 0x3f, 0x55, 0x5e, 0x2a, 0x42, 0xcf, + 0x2b, 0x6d, 0xf2, 0x12, 0xba, 0x5e, 0xee, 0x5c, 0x24, 0x5c, 0x18, 0x43, 0x0c, 0xb0, 0x73, 0x4b, + 0x80, 0x93, 0x84, 0x0b, 0xa5, 0xd6, 0x3c, 0x34, 0x0a, 0x69, 0x9a, 0x30, 0x61, 0x8c, 0x3e, 0x2a, + 0x3d, 0x4d, 0x58, 0x25, 0x95, 0x06, 0xf9, 0x16, 0x34, 0x2f, 0x77, 0xb2, 0x30, 0x30, 0x36, 0x51, + 0xf9, 0xe8, 0x16, 0xe5, 0x79, 0x18, 0x28, 0x61, 0xc7, 0x93, 0xdf, 0xe4, 0x7b, 0x18, 0x7a, 0xb9, + 0x43, 0x7f, 0xa5, 0x7e, 0x26, 0x5c, 0x2f, 0xa2, 0xc6, 0x18, 0xe5, 0x9f, 0xdf, 0x22, 0xb7, 0xd6, + 0x8e, 0x2a, 0xca, 0xc0, 0xab, 0x41, 0xe4, 0x0b, 0xd0, 0xa8, 0xbc, 0x2c, 0xdc, 0xd8, 0xc2, 0x28, + 0x9b, 0x55, 0x14, 0xbc, 0x44, 0x76, 0x41, 0x4f, 0x5e, 0xc1, 0xa0, 0x7e, 0x00, 0x64, 0x0c, 0xad, + 0xf7, 0x34, 0x2f, 0x9a, 0x5a, 0x7e, 0xca, 0x56, 0xbe, 0x72, 0xa3, 0x8c, 0x96, 0xad, 0x8c, 0xc6, + 0xab, 0xe6, 0x8b, 0xc6, 0xe4, 0x35, 0x8c, 0x3e, 0x2c, 0xfe, 0x9d, 0xd4, 0x2f, 0xa1, 0x5f, 0xab, + 0xfc, 0xdd, 0xa5, 0xeb, 0xca, 0xdf, 0x49, 0xfa, 0x02, 0xa0, 0x2a, 0xfd, 0x9d, 0x94, 0xdf, 0xc1, + 0xd6, 0x8d, 0xaa, 0xdf, 0x25, 0x80, 0x39, 0x83, 0xfe, 0x69, 0x18, 0xaf, 0x6c, 0xfa, 0x73, 0x46, + 0xb9, 0x20, 0x23, 0x68, 0x86, 0x01, 0x2a, 0xdb, 0x76, 0x33, 0x0c, 0xc8, 0x33, 0xe8, 0x70, 0xe1, + 0x0a, 0x7e, 0x73, 0x7a, 0x55, 0xe7, 0x6e, 0x2b, 0x17, 0xf3, 0x21, 0xf4, 0x54, 0xa8, 0x34, 0xca, + 0xaf, 0x07, 0x32, 0xff, 0x68, 0x02, 0x54, 0x03, 0x4f, 0xde, 0xfd, 0x32, 0x52, 0x91, 0xe7, 0xda, + 0x26, 0xdb, 0xa0, 0x71, 0xe6, 0x3b, 0x61, 0x8a, 0x8b, 0xf6, 0xec, 0x0e, 0x67, 0xfe, 0x2c, 0x25, + 0xff, 0x07, 0x5d, 0xc2, 0xd8, 0xfe, 0x72, 0x52, 0x0d, 0xed, 0x2e, 0x67, 0x3e, 0x76, 0xf7, 0x36, + 0x68, 0x01, 0x17, 0x52, 0xd1, 0x56, 0x8a, 0x80, 0x0b, 0xa5, 0x90, 0x30, 0xde, 0xb5, 0x0e, 0x12, + 0xdd, 0x80, 0x0b, 0xbc, 0x4a, 0x05, 0x85, 0xc1, 0x34, 0x15, 0x2c, 0xe0, 0x02, 0x83, 0xfd, 0x0f, + 0xba, 0x19, 0xa7, 0xcc, 0x09, 0xd5, 0x54, 0x1a, 0xda, 0x9a, 0x34, 0x67, 0x01, 0xf9, 0x04, 0x20, + 0x65, 0x89, 0x4f, 0x39, 0x97, 0x9c, 0x8e, 0x5c, 0xaf, 0x40, 0x66, 0x01, 0x79, 0x0c, 0x83, 0x92, + 0x4e, 0x5d, 0x71, 0x81, 0xb3, 0xa9, 0x67, 0xf7, 0x0b, 0xec, 0xd4, 0x15, 0x17, 0x75, 0x17, 0x97, + 0xad, 0xe4, 0x7c, 0x6a, 0xd5, 0x5c, 0xa6, 0x6c, 0xc5, 0xcd, 0x39, 0xe8, 0xcb, 0x94, 0x32, 0x57, + 0x24, 0x0c, 0xdf, 0x94, 0x3c, 0xad, 0xde, 0x94, 0x3c, 0xa5, 0x72, 0x30, 0x26, 0x92, 0x8f, 0x83, + 0xa2, 0x3a, 0xa5, 0x29, 0xbd, 0x03, 0x57, 0xb8, 0x58, 0x9b, 0x9e, 0x8d, 0xdf, 0xe6, 0x6f, 0xd0, + 0x96, 0xaf, 0x86, 0xe4, 0x62, 0xb7, 0x7a, 0x9d, 0xe4, 0xb7, 0x9c, 0xfb, 0x6e, 0xf5, 0x32, 0xf5, + 0xec, 0xc2, 0x92, 0x47, 0x13, 0x64, 0xcc, 0x45, 0x46, 0xc5, 0x5a, 0xdb, 0x64, 0x0f, 0xf4, 0xa4, + 0xc8, 0x0e, 0x4b, 0xdd, 0xdf, 0x27, 0x55, 0x47, 0x94, 0x79, 0xdb, 0x6b, 0x1f, 0xf3, 0x9f, 0x06, + 0x0c, 0x0e, 0xa3, 0x90, 0xc6, 0xe2, 0x30, 0x89, 0xdf, 0x85, 0xab, 0x1b, 0xfd, 0x55, 0x26, 0xd6, + 0xac, 0x25, 0x66, 0x40, 0xb7, 0x7c, 0xc6, 0xd4, 0xfa, 0xa5, 0x49, 0xbe, 0x84, 0xad, 0x90, 0x1f, + 0x85, 0x8c, 0xfe, 0xe2, 0x46, 0x91, 0x9d, 0xc5, 0x71, 0x18, 0xaf, 0x30, 0x0f, 0xdd, 0xbe, 0x49, + 0xc8, 0x0d, 0xfa, 0xb8, 0x6a, 0x71, 0xf8, 0x85, 0x25, 0x37, 0x18, 0x25, 0xab, 0x39, 0xbd, 0xa2, + 0x51, 0x71, 0xf6, 0x6b, 0x9b, 0x3c, 0x2d, 0x9f, 0xc8, 0x2e, 0x4e, 0xa8, 0xeb, 0xaf, 0xaf, 0x22, + 0xcd, 0xbf, 0x1a, 0x30, 0x58, 0x24, 0x22, 0x7c, 0x17, 0xfa, 0xaa, 0x2e, 0xd7, 0xb7, 0xf5, 0x29, + 0x80, 0x8f, 0xdb, 0x5e, 0x54, 0x9b, 0xab, 0x21, 0x92, 0xe7, 0x94, 0x5d, 0x51, 0x86, 0xbc, 0xda, + 0x65, 0x0d, 0x21, 0x4f, 0x8b, 0x93, 0x97, 0x7b, 0x1b, 0xed, 0x8f, 0xab, 0x2c, 0xa6, 0xea, 0xff, + 0x82, 0xea, 0x85, 0xf2, 0xc4, 0x3b, 0xd5, 0x89, 0x57, 0x1b, 0xd0, 0x3e, 0xb2, 0x81, 0x67, 0xbf, + 0x37, 0x40, 0x53, 0xa1, 0x88, 0x0e, 0xed, 0xc5, 0x72, 0x61, 0x8d, 0x37, 0xc8, 0x16, 0x0c, 0xe7, + 0xcb, 0xe9, 0x1b, 0xe7, 0x68, 0x66, 0x5b, 0x3f, 0x4d, 0xe7, 0xf3, 0x71, 0x83, 0xdc, 0x83, 0xcd, + 0xf3, 0xc5, 0x87, 0x60, 0x53, 0xfa, 0x1d, 0x9e, 0x4c, 0x17, 0xc7, 0x96, 0x73, 0xb8, 0x5c, 0x1c, + 0xcd, 0x8e, 0xc7, 0x2d, 0xb2, 0x09, 0x7d, 0x6b, 0x31, 0x3d, 0x98, 0x5b, 0x8e, 0x7d, 0x3e, 0xb7, + 0xc6, 0x6d, 0x32, 0x86, 0xc1, 0x9b, 0xd9, 0x59, 0x85, 0x74, 0xc8, 0x10, 0x7a, 0xf3, 0xe5, 0xb1, + 0x33, 0xb7, 0xde, 0x5a, 0xf3, 0xb1, 0x26, 0x97, 0x3d, 0xfb, 0x71, 0x79, 0x3a, 0xee, 0xee, 0xff, + 0xd9, 0x80, 0xe6, 0xf9, 0x8c, 0x3c, 0x87, 0xb6, 0x9c, 0x1e, 0x64, 0xbb, 0xca, 0xb8, 0x36, 0x98, + 0x26, 0xf7, 0xae, 0xc3, 0x69, 0x94, 0x9b, 0x1b, 0xe4, 0x6b, 0xe8, 0x4e, 0xf9, 0x7b, 0xec, 0xf1, + 0xff, 0xfc, 0x67, 0x35, 0xb9, 0x56, 0x00, 0x73, 0x83, 0x58, 0x30, 0xac, 0x9f, 0x1d, 0x27, 0x0f, + 0x6a, 0xc2, 0x5a, 0xaf, 0x4e, 0x6a, 0x78, 0x5d, 0x60, 0x6e, 0xec, 0x36, 0xbe, 0x6a, 0x78, 0x1a, + 0x92, 0xdf, 0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xda, 0x87, 0x08, 0x47, 0x16, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -432,11 +682,13 @@ var _ grpc.ClientConn // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 -// Client API for UI service - +// UIClient is the client API for UI service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type UIClient interface { Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingReply, error) AskRule(ctx context.Context, in *Connection, opts ...grpc.CallOption) (*Rule, error) + Notifications(ctx context.Context, opts ...grpc.CallOption) (UI_NotificationsClient, error) } type uIClient struct { @@ -449,7 +701,7 @@ func NewUIClient(cc *grpc.ClientConn) UIClient { func (c *uIClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingReply, error) { out := new(PingReply) - err := grpc.Invoke(ctx, "/protocol.UI/Ping", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/protocol.UI/Ping", in, out, opts...) if err != nil { return nil, err } @@ -458,18 +710,63 @@ func (c *uIClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallO func (c *uIClient) AskRule(ctx context.Context, in *Connection, opts ...grpc.CallOption) (*Rule, error) { out := new(Rule) - err := grpc.Invoke(ctx, "/protocol.UI/AskRule", in, out, c.cc, opts...) + err := c.cc.Invoke(ctx, "/protocol.UI/AskRule", in, out, opts...) if err != nil { return nil, err } return out, nil } -// Server API for UI service +func (c *uIClient) Notifications(ctx context.Context, opts ...grpc.CallOption) (UI_NotificationsClient, error) { + stream, err := c.cc.NewStream(ctx, &_UI_serviceDesc.Streams[0], "/protocol.UI/Notifications", opts...) + if err != nil { + return nil, err + } + x := &uINotificationsClient{stream} + return x, nil +} +type UI_NotificationsClient interface { + Send(*ClientConfig) error + Recv() (*Notification, error) + grpc.ClientStream +} + +type uINotificationsClient struct { + grpc.ClientStream +} + +func (x *uINotificationsClient) Send(m *ClientConfig) error { + return x.ClientStream.SendMsg(m) +} + +func (x *uINotificationsClient) Recv() (*Notification, error) { + m := new(Notification) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// UIServer is the server API for UI service. type UIServer interface { Ping(context.Context, *PingRequest) (*PingReply, error) AskRule(context.Context, *Connection) (*Rule, error) + Notifications(UI_NotificationsServer) error +} + +// UnimplementedUIServer can be embedded to have forward compatible implementations. +type UnimplementedUIServer struct { +} + +func (*UnimplementedUIServer) Ping(ctx context.Context, req *PingRequest) (*PingReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (*UnimplementedUIServer) AskRule(ctx context.Context, req *Connection) (*Rule, error) { + return nil, status.Errorf(codes.Unimplemented, "method AskRule not implemented") +} +func (*UnimplementedUIServer) Notifications(srv UI_NotificationsServer) error { + return status.Errorf(codes.Unimplemented, "method Notifications not implemented") } func RegisterUIServer(s *grpc.Server, srv UIServer) { @@ -512,6 +809,32 @@ func _UI_AskRule_Handler(srv interface{}, ctx context.Context, dec func(interfac return interceptor(ctx, in, info, handler) } +func _UI_Notifications_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(UIServer).Notifications(&uINotificationsServer{stream}) +} + +type UI_NotificationsServer interface { + Send(*Notification) error + Recv() (*ClientConfig, error) + grpc.ServerStream +} + +type uINotificationsServer struct { + grpc.ServerStream +} + +func (x *uINotificationsServer) Send(m *Notification) error { + return x.ServerStream.SendMsg(m) +} + +func (x *uINotificationsServer) Recv() (*ClientConfig, error) { + m := new(ClientConfig) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + var _UI_serviceDesc = grpc.ServiceDesc{ ServiceName: "protocol.UI", HandlerType: (*UIServer)(nil), @@ -525,65 +848,13 @@ var _UI_serviceDesc = grpc.ServiceDesc{ Handler: _UI_AskRule_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Notifications", + Handler: _UI_Notifications_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, Metadata: "ui.proto", } - -func init() { proto.RegisterFile("ui.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 838 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x6d, 0x6f, 0xdc, 0x44, - 0x10, 0x6e, 0xee, 0xc5, 0x67, 0xcf, 0xbd, 0xb4, 0x5d, 0x1a, 0x58, 0xae, 0x42, 0xbd, 0xba, 0x02, - 0x22, 0x3e, 0x9c, 0x44, 0xa8, 0x50, 0x5b, 0x55, 0x42, 0x29, 0x8a, 0xd4, 0x13, 0x20, 0xa2, 0x45, - 0xe5, 0xab, 0x65, 0x7b, 0x57, 0x89, 0xd5, 0x8b, 0xd7, 0xec, 0xac, 0x23, 0xfc, 0x85, 0x7f, 0xc3, - 0x6f, 0xe1, 0x6f, 0xa1, 0x9d, 0xb5, 0xcf, 0x47, 0x4a, 0x2a, 0xdd, 0xa7, 0xdb, 0xe7, 0x79, 0xe6, - 0x99, 0x1b, 0x8d, 0x67, 0x67, 0x21, 0xac, 0x8b, 0x75, 0x65, 0xb4, 0xd5, 0x2c, 0xa4, 0x9f, 0x5c, - 0x6f, 0xe3, 0x1a, 0xc6, 0xe7, 0x37, 0xaa, 0xb4, 0x8c, 0xc1, 0xc8, 0x16, 0xd7, 0x8a, 0x1f, 0xad, - 0x8e, 0x4e, 0x22, 0x41, 0x67, 0xf6, 0x1c, 0x20, 0xd7, 0x65, 0xa9, 0x72, 0x5b, 0xe8, 0x92, 0x0f, - 0x56, 0x47, 0x27, 0xd3, 0xd3, 0x47, 0xeb, 0xce, 0xbb, 0xfe, 0x71, 0xa7, 0x89, 0xbd, 0x38, 0x16, - 0xc3, 0xc8, 0xd4, 0x5b, 0xc5, 0x87, 0x14, 0xbf, 0xe8, 0xe3, 0x45, 0xbd, 0x55, 0x82, 0xb4, 0xf8, - 0x9f, 0x10, 0xe0, 0x37, 0x9b, 0xda, 0x02, 0x6d, 0x91, 0x23, 0xfb, 0x12, 0x16, 0x32, 0x55, 0xd7, - 0xba, 0x4c, 0x6e, 0x94, 0x41, 0xf7, 0x67, 0xbe, 0x8c, 0xb9, 0x67, 0x7f, 0xf7, 0x24, 0x7b, 0x04, - 0x63, 0xe7, 0x46, 0x2a, 0x65, 0x24, 0x3c, 0x60, 0x9f, 0x42, 0x50, 0x57, 0x54, 0xfb, 0x90, 0xe8, - 0x16, 0xb1, 0x67, 0x30, 0x97, 0x25, 0x26, 0x46, 0x61, 0xa5, 0x4b, 0x54, 0xc8, 0x47, 0x24, 0xcf, - 0x64, 0x89, 0xa2, 0xe3, 0xd8, 0x0a, 0xa6, 0x7d, 0xe9, 0xc8, 0xc7, 0x14, 0xb2, 0x4f, 0x31, 0x0e, - 0x93, 0xe2, 0xb2, 0xd4, 0x46, 0x49, 0x1e, 0x90, 0xda, 0x41, 0xb6, 0x84, 0x30, 0xcd, 0x73, 0x55, - 0x59, 0x25, 0xf9, 0x84, 0xa4, 0x1d, 0x76, 0x2e, 0x69, 0x74, 0x55, 0x29, 0xc9, 0x43, 0xef, 0x6a, - 0x21, 0x7b, 0x0c, 0x91, 0xab, 0x3b, 0xb9, 0x2a, 0x2c, 0xf2, 0xc8, 0xdb, 0x1c, 0xf1, 0xb6, 0xb0, - 0xc8, 0x9e, 0xc0, 0x94, 0xc4, 0xeb, 0x02, 0x5d, 0xc5, 0x40, 0x32, 0x38, 0xea, 0x17, 0x62, 0xd8, - 0x6b, 0x08, 0xb3, 0x26, 0xa1, 0x96, 0xf2, 0xe9, 0x6a, 0x78, 0x32, 0x3d, 0x7d, 0xda, 0x37, 0xb8, - 0xef, 0xe8, 0xfa, 0x4d, 0x73, 0xe1, 0xd8, 0xf3, 0xd2, 0x9a, 0x46, 0x4c, 0x32, 0x8f, 0xd8, 0x1b, - 0x80, 0xac, 0x49, 0x52, 0x29, 0x8d, 0x42, 0xe4, 0x33, 0xf2, 0x3f, 0xbb, 0xc3, 0x7f, 0xe6, 0xa3, - 0x7c, 0x86, 0x28, 0xeb, 0x30, 0x7b, 0x09, 0x93, 0xac, 0x49, 0xae, 0x34, 0x5a, 0x3e, 0xa7, 0x04, - 0xab, 0x3b, 0x12, 0xbc, 0xd5, 0x68, 0xbd, 0x3b, 0xc8, 0x08, 0xb4, 0xd6, 0x4a, 0x1b, 0xcb, 0x17, - 0x1f, 0xb5, 0x5e, 0x68, 0xd3, 0x5b, 0x1d, 0x60, 0xdf, 0x43, 0x90, 0x35, 0x49, 0x5d, 0x48, 0x7e, - 0x9f, 0x9c, 0x4f, 0xee, 0x70, 0xbe, 0x2b, 0xa4, 0x37, 0x8e, 0x33, 0x77, 0x66, 0x3f, 0xc1, 0x3c, - 0x6b, 0x12, 0xf5, 0xa7, 0xca, 0x6b, 0x9b, 0x66, 0x5b, 0xc5, 0x1f, 0x90, 0xfd, 0xab, 0x3b, 0xec, - 0xe7, 0xbb, 0x40, 0x9f, 0x65, 0x96, 0xed, 0x51, 0xec, 0x6b, 0x08, 0x94, 0xbb, 0x2c, 0xc8, 0x1f, - 0x52, 0x96, 0xfb, 0x7d, 0x16, 0xba, 0x44, 0xa2, 0x95, 0x97, 0xaf, 0x60, 0xb6, 0xff, 0x01, 0xd8, - 0x03, 0x18, 0xbe, 0x57, 0x4d, 0x3b, 0xd4, 0xee, 0xe8, 0x46, 0xf9, 0x26, 0xdd, 0xd6, 0xaa, 0x1b, - 0x65, 0x02, 0xaf, 0x06, 0x2f, 0x8e, 0x96, 0xaf, 0x61, 0xf1, 0xdf, 0xe6, 0x1f, 0xe4, 0x7e, 0x09, - 0xd3, 0xbd, 0xce, 0x1f, 0x6e, 0xdd, 0x75, 0xfe, 0x20, 0xeb, 0x0b, 0x80, 0xbe, 0xf5, 0x07, 0x39, - 0x7f, 0x80, 0x87, 0x1f, 0x74, 0xfd, 0x90, 0x04, 0xf1, 0x06, 0xa6, 0x17, 0x45, 0x79, 0x29, 0xd4, - 0x1f, 0xb5, 0x42, 0xcb, 0x16, 0x30, 0x28, 0x24, 0x39, 0x47, 0x62, 0x50, 0x48, 0xf6, 0x0d, 0x8c, - 0xd1, 0xa6, 0x16, 0x3f, 0xdc, 0x5e, 0xfd, 0x77, 0x17, 0x3e, 0x24, 0x7e, 0x0c, 0x91, 0x4f, 0x55, - 0x6d, 0x9b, 0xdb, 0x89, 0xe2, 0xbf, 0x07, 0x00, 0xfd, 0xc2, 0x73, 0x77, 0xbf, 0xcb, 0xd4, 0xd6, - 0xb9, 0xc3, 0xec, 0x18, 0x02, 0x34, 0x79, 0x52, 0x54, 0xf4, 0xa7, 0x91, 0x18, 0xa3, 0xc9, 0x37, - 0x15, 0xfb, 0x1c, 0x42, 0x47, 0xd3, 0xf8, 0xbb, 0x4d, 0x35, 0x17, 0x13, 0x34, 0x39, 0x4d, 0xf7, - 0x31, 0x04, 0x12, 0xad, 0x73, 0x8c, 0xbc, 0x43, 0xa2, 0xf5, 0x0e, 0x47, 0xd3, 0x5d, 0x1b, 0x93, - 0x30, 0x91, 0x68, 0xe9, 0x2a, 0xb5, 0x12, 0x25, 0x0b, 0x7c, 0x32, 0x89, 0x96, 0x92, 0x7d, 0x06, - 0x93, 0x1a, 0x95, 0x49, 0x0a, 0xbf, 0x95, 0xe6, 0x22, 0x70, 0x70, 0x23, 0xd9, 0x17, 0x00, 0x95, - 0xd1, 0xb9, 0x42, 0x74, 0x5a, 0x48, 0x5a, 0xd4, 0x32, 0x1b, 0xc9, 0x9e, 0xc2, 0xac, 0x93, 0xab, - 0xd4, 0x5e, 0xd1, 0x6e, 0x8a, 0xc4, 0xb4, 0xe5, 0x2e, 0x52, 0x7b, 0xb5, 0x1f, 0x92, 0x9a, 0x4b, - 0xb7, 0x9f, 0x86, 0x7b, 0x21, 0x67, 0xe6, 0x12, 0xe3, 0x9f, 0x21, 0xfc, 0xb5, 0x52, 0x26, 0xb5, - 0xda, 0xd0, 0x9b, 0xd2, 0x54, 0xfd, 0x9b, 0xd2, 0x54, 0xca, 0x2d, 0x46, 0xed, 0xf4, 0x52, 0xb6, - 0xdd, 0xe9, 0xa0, 0x8b, 0x96, 0xa9, 0x4d, 0xa9, 0x37, 0x91, 0xa0, 0x73, 0xfc, 0x17, 0x8c, 0xdc, - 0xab, 0xe1, 0xb4, 0x32, 0xed, 0x5f, 0x27, 0x77, 0x76, 0x7b, 0x3f, 0xed, 0x5f, 0xa6, 0x48, 0xb4, - 0xc8, 0x7d, 0x1a, 0x59, 0x9b, 0x94, 0x14, 0x9f, 0x6b, 0x87, 0xd9, 0x1a, 0x42, 0xdd, 0x56, 0x47, - 0xad, 0x9e, 0x9e, 0xb2, 0x7e, 0x22, 0xba, 0xba, 0xc5, 0x2e, 0xe6, 0xf4, 0x1a, 0x06, 0xef, 0x36, - 0xec, 0x39, 0x8c, 0xdc, 0x60, 0xb0, 0xe3, 0x3e, 0x76, 0x6f, 0xe6, 0x96, 0x9f, 0xdc, 0xa6, 0xab, - 0x6d, 0x13, 0xdf, 0x63, 0xdf, 0xc2, 0xe4, 0x0c, 0xdf, 0x53, 0xf9, 0xff, 0xfb, 0x68, 0x2e, 0x6f, - 0x3d, 0x8d, 0xf1, 0xbd, 0x2c, 0x20, 0xe2, 0xbb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x81, 0x94, - 0x16, 0x93, 0xaa, 0x07, 0x00, 0x00, -} diff --git a/proto/ui.proto b/proto/ui.proto index 7ee0afc6..06b73c96 100644 --- a/proto/ui.proto +++ b/proto/ui.proto @@ -5,6 +5,7 @@ package protocol; service UI { rpc Ping(PingRequest) returns (PingReply) {} rpc AskRule (Connection) returns (Rule) {} + rpc Notifications (stream ClientConfig) returns (stream Notification) {} } message Event { @@ -67,3 +68,35 @@ message Rule { string duration = 3; Operator operator = 4; } + +enum Action { + NONE = 0; + LOAD_FIREWALL = 1; + UNLOAD_FIREWALL = 2; + CHANGE_CONFIG = 3; + ENABLE_RULE = 4; + DISABLE_RULE = 5; + LOG_LEVEL = 6; + STOP = 7; +} + +message ClientConfig { + uint64 id = 1; + string name = 2; + string version = 3; + bool isFirewallRunning = 4; + // daemon configuration as json string + string config = 5; + uint32 logLevel = 6; + repeated Rule rules = 7; +} + +message Notification { + uint64 id = 1; + string clientName = 2; + string serverName = 3; + // CHANGE_CONFIG: 2, data: {"default_timeout": 1, ...} + Action type = 4; + string data = 5; + repeated Rule rules = 6; +}