From 43b1147106bcab679f2abcd7ddd6c2e6e8bd9596 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Fri, 22 Dec 2023 01:44:50 +0100 Subject: [PATCH] Implement network connection handling Introduced a new Connection struct and related functions in `connection.go` to facilitate network connections. Incorporated the `go-parsesyslog` package to parse incoming network data. Implemented functions in `server.go` to accept and handle incoming network connections, bolstering the application's network interaction functionality. --- connection.go | 27 +++++++++++++++++++++++++++ go.mod | 5 ++++- go.sum | 2 ++ server.go | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 connection.go diff --git a/connection.go b/connection.go new file mode 100644 index 0000000..47c862f --- /dev/null +++ b/connection.go @@ -0,0 +1,27 @@ +package logranger + +import ( + "bufio" + "net" +) + +// Connection represents a connection to a network resource. +type Connection struct { + conn net.Conn + id string + rb *bufio.Reader + wb *bufio.Writer +} + +// NewConnection creates a new Connection object with the provided net.Conn. +// The Connection object holds a reference to the provided net.Conn, along with an ID string, +// bufio.Reader, and bufio.Writer. It returns a pointer to the created Connection object. +func NewConnection(nc net.Conn) *Connection { + c := &Connection{ + conn: nc, + id: "foo", + rb: bufio.NewReader(nc), + wb: bufio.NewWriter(nc), + } + return c +} diff --git a/go.mod b/go.mod index 67413c9..cd342f1 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,10 @@ module github.com/wneessen/logranger go 1.21 -require github.com/kkyr/fig v0.4.0 +require ( + github.com/kkyr/fig v0.4.0 + github.com/wneessen/go-parsesyslog v0.2.1 +) require ( github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index 0157e46..7d45465 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/wneessen/go-parsesyslog v0.2.1 h1:T6a6BsLb4plF1wG6MJ0aJDNtXE2Y28PMdCN97HmJi8A= +github.com/wneessen/go-parsesyslog v0.2.1/go.mod h1:xk+PXAOW/9Vc6AfrXd1tZKFyndq1jwxK+rIdlKuHpcc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/server.go b/server.go index 21810e3..3b48788 100644 --- a/server.go +++ b/server.go @@ -11,6 +11,11 @@ import ( "os" "strings" "sync" + + "github.com/wneessen/go-parsesyslog" + _ "github.com/wneessen/go-parsesyslog/rfc3164" + "github.com/wneessen/go-parsesyslog/rfc5424" + _ "github.com/wneessen/go-parsesyslog/rfc5424" ) const ( @@ -63,7 +68,10 @@ func (s *Server) RunWithListener(l net.Listener) error { s.log.Error("failed to create PID file", LogErrKey, err) os.Exit(1) } - _, err = pf.WriteString(fmt.Sprintf("%d", os.Getpid())) + pid := os.Getpid() + s.log.Debug("creating PID file", slog.String("pid_file", pf.Name()), + slog.Int("pid", pid)) + _, err = pf.WriteString(fmt.Sprintf("%d", pid)) if err != nil { s.log.Error("failed to write PID to PID file", LogErrKey, err) _ = pf.Close() @@ -74,10 +82,47 @@ func (s *Server) RunWithListener(l net.Listener) error { // Listen for connections s.wg.Add(1) + go s.Listen() return nil } +func (s *Server) Listen() { + defer s.wg.Done() + s.log.Info("listening for new connections", slog.String("listen_addr", s.listener.Addr().String())) + for { + c, err := s.listener.Accept() + if err != nil { + s.log.Error("failed to accept new connection", LogErrKey, err) + continue + } + s.log.Debug("accepted new connection", slog.String("remote_addr", c.RemoteAddr().String())) + conn := NewConnection(c) + s.wg.Add(1) + go func(co *Connection) { + s.HandleConnection(co) + s.wg.Done() + }(conn) + } +} + +func (s *Server) HandleConnection(c *Connection) { + s.log.Debug("handling connection") + defer c.conn.Close() + pa, err := parsesyslog.New(rfc5424.Type) + if err != nil { + s.log.Error("failed to initialize logger", LogErrKey, err) + return + } + lm, err := pa.ParseReader(c.rb) + if err != nil { + s.log.Error("failed to parse message", LogErrKey, err) + return + } + s.log.Info("log message received", slog.String("message", lm.Message.String())) + +} + // setLogLevel sets the log level based on the value of `s.conf.Log.Level`. // It creates a new `slog.HandlerOptions` and assigns the corresponding `slog.Level` // based on the value of `s.conf.Log.Level`. If the value is not one of the valid levels,