diff --git a/Makefile b/Makefile index ad8155e..ae508bb 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,8 @@ VERSION = $(shell git describe --tags) BUILDTIME = $(shell date +%Y.%m.%d_%H%M) -all: portmap.pb.go build - ./gus --version - ./gus --no-gui --config /etc/gus/gus.text +all: proto build + ./gus --config /etc/gus/gus.text gocui: build ./gus --gui gocui --config /etc/gus/gus.text >/tmp/gocui.log 2>&1 @@ -36,9 +35,14 @@ clean: rm -f go.* *.pb.go rm -f gus +proto: portmap.pb.go event.pb.go + portmap.pb.go: portmap.proto autogenpb --proto portmap.proto +event.pb.go: event.proto + autogenpb --proto event.proto + list: curl "http://localhost:2522/list" diff --git a/doGui.go b/doGui.go index 09bb828..ab03b89 100644 --- a/doGui.go +++ b/doGui.go @@ -51,11 +51,20 @@ func doGui() { makePortmapWin() }) - grid.NewButton("Events", func() { + grid.NewButton("Save Events", func() { log.Info("event log is len =", me.events.Len()) me.events.Save() }) + grid.NewButton("Show Last 20 Events", func() { + // if the window exists, just toggle it open or closed + if me.eventswin != nil { + me.eventswin.Toggle() + return + } + makeEventsWin() + }) + // sit here forever refreshing the GUI for { refresh() diff --git a/event.proto b/event.proto new file mode 100644 index 0000000..b0c29d7 --- /dev/null +++ b/event.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package gus; + +import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp + +message Event { + string hostname = 1; // the hostname of the client + string address = 2; // the IP address from the client + string where = 3; // where gus was sending the client traffic + google.protobuf.Timestamp ctime = 4; // when the socket opened + google.protobuf.Timestamp etime = 5; // when the socket ended +} + +message Events { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex` + string uuid = 1; // `autogenpb:uuid:4e91f9e6-f545-4c72-bec4-ab951276da1d` + string version = 2; // `autogenpb:version:v0.0.1` + repeated Event events = 3; +} diff --git a/main.go b/main.go index dab140e..916dc3a 100644 --- a/main.go +++ b/main.go @@ -67,6 +67,16 @@ func main() { startHTTP() os.Exit(0) } + + all := me.portmaps.All() + for all.Scan() { + pm := all.Next() + if !pm.Enabled { + continue + } + log.Info("portmap enabled for port", pm.Listen, "to", pm.Connect) + go gus3000(int(pm.Listen), pm.Connect) + } // go NewWatchdog() go startHTTP() doGui() @@ -92,11 +102,11 @@ func gus3000(port int, connect string) { // log.Printf("Client connected: %s", clientConn.RemoteAddr()) // Handle the connection in a separate goroutine - go handleConnection(clientConn, connect) + go handleConnection(clientConn, connect, port) } } -func handleConnection(clientConn net.Conn, where string) { +func handleConnection(clientConn net.Conn, where string, localport int) { defer clientConn.Close() // Connect to the target server @@ -108,7 +118,7 @@ func handleConnection(clientConn net.Conn, where string) { } defer targetConn.Close() // log.Printf("Connected to target server: %s where = %s\n", targetConn.RemoteAddr(), where) - log.Printf("Connected to client: %s where = %s\n", clientConn.RemoteAddr(), where) + log.Printf("Connected on port %d from client: %s to where = %s\n", localport, clientConn.RemoteAddr(), where) e := new(Event) e.Address = fmt.Sprintf("%s\n", clientConn.RemoteAddr()) diff --git a/portmap.proto b/portmap.proto index ac543e3..2a0d627 100644 --- a/portmap.proto +++ b/portmap.proto @@ -2,31 +2,15 @@ syntax = "proto3"; package gus; -import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp - -message Event { - string hostname = 1; // the hostname of the client - string address = 2; // the IP address from the client - string where = 3; // where gus was sending the client traffic - google.protobuf.Timestamp ctime = 4; // when the socket opened - google.protobuf.Timestamp etime = 5; // when the socket ended -} - -message Events { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex` - string uuid = 1; - string version = 2; - repeated Event events = 3; -} - message Portmap { - int64 listen = 1; // `autogenpb:unique` - string connect = 2; // `autogenpb:unique` - bool enabled = 3; - string uuid = 4; + int64 listen = 1; // `autogenpb:unique` + string connect = 2; // `autogenpb:unique` + bool enabled = 3; + bool allowIPv4 = 4; } -message Portmaps { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex` - string uuid = 1; // `autogenpb:uuid:49a865ea-292d-48fd-8dc2-d0f82d5fd016` - string version = 2; // `autogenpb:version:v0.0.1` - repeated Portmap portmaps = 3; +message Portmaps { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:nomutex` + string uuid = 1; // `autogenpb:uuid:49a865ea-292d-48fd-8dc2-d0f82d5fd016` + string version = 2; // `autogenpb:version:v0.0.1` + repeated Portmap portmaps = 3; } diff --git a/structs.go b/structs.go index d96bf0b..91299b9 100644 --- a/structs.go +++ b/structs.go @@ -15,16 +15,17 @@ var me *gusconf // this app's variables type gusconf struct { - myGui *gui.Node // the base of the gui - portmaps *Portmaps // the portmap window - events *Events // the event log - portwin *stdTableWin // the portwin window - urlbase string // the dns name for the zookeeper - hostname string // my hostname - pollDelay time.Duration // how often to report our status - dog *time.Ticker // the watchdog timer - failcount int // how many times we've failed to contact the zookeeper - failcountmax int // after this, exit and let systemd restart the daemon + myGui *gui.Node // the base of the gui + portmaps *Portmaps // the portmap window + events *Events // the event log + portwin *stdTableWin // the portwin window + eventswin *stdEventTableWin // the event window + urlbase string // the dns name for the zookeeper + hostname string // my hostname + pollDelay time.Duration // how often to report our status + dog *time.Ticker // the watchdog timer + failcount int // how many times we've failed to contact the zookeeper + failcountmax int // after this, exit and let systemd restart the daemon } type stdTableWin struct { @@ -44,3 +45,21 @@ func (w *stdTableWin) Toggle() { } w.win.Toggle() } + +type stdEventTableWin struct { + sync.Mutex + win *gadgets.GenericWindow // the machines gui window + box *gui.Node // the machines gui parent box widget + TB *EventsTable // the gui table buffer + update bool // if the window should be updated +} + +func (w *stdEventTableWin) Toggle() { + if w == nil { + return + } + if w.win == nil { + return + } + w.win.Toggle() +} diff --git a/windowEvents.go b/windowEvents.go new file mode 100644 index 0000000..20a102d --- /dev/null +++ b/windowEvents.go @@ -0,0 +1,67 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +import ( + "go.wit.com/gui" + "go.wit.com/lib/gadgets" + "go.wit.com/log" +) + +func makeEventsWin() { + me.eventswin = new(stdEventTableWin) + me.eventswin.win = gadgets.NewGenericWindow("zood daemon versions", "todo: add global controls here") + me.eventswin.win.Custom = func() { + log.Info("test delete window here") + } + grid := me.eventswin.win.Group.RawGrid() + grid.NewButton("ConfigSave() ", func() { + saveMachineState() + }) + grid.NewButton("Add() ", func() { + }) + grid.NewCheckbox("hide active") + grid.NewButton("update", func() { + doMachinesUpgradeTable() + }) + + // make a box at the bottom of the window for the protobuf table + me.eventswin.box = me.eventswin.win.Bottom.Box().SetProgName("TBOX") + doEventsTable(me.events) +} + +func doEventsTable(currentEvents *Events) { + me.eventswin.Lock() + defer me.eventswin.Unlock() + if me.eventswin.TB != nil { + me.eventswin.TB.Delete() + me.eventswin.TB = nil + } + + // display the protobuf + me.eventswin.TB = AddEventsPB(me.eventswin.box, currentEvents) + f := func(e *Event) { + log.Info("Triggered. do something here", e.Hostname) + // m.Enabled = true + } + me.eventswin.TB.Custom(f) + // log.Info("table has uuid", me.eventswin.TB.GetUuid()) +} + +func AddEventsPB(tbox *gui.Node, pb *Events) *EventsTable { + t := pb.NewTable("EventsPB") + t.NewUuid() + t.SetParent(tbox) + + enabledf := func(p *Event) string { + return "todo" + } + t.AddStringFunc("enabled", enabledf) + + t.AddHostname() + t.AddAddress() + t.AddWhere() + t.ShowTable() + return t +}