diff --git a/cmd/circologd/activation.go b/cmd/circologd/activation.go new file mode 100644 index 0000000..53387c7 --- /dev/null +++ b/cmd/circologd/activation.go @@ -0,0 +1,39 @@ +package main + +import ( + "net" + + "github.com/coreos/go-systemd/activation" +) + +func Listeners() ([]net.Listener, error) { + files := activation.Files(false) + listeners := make([]net.Listener, len(files)) + + for i, f := range files { + if pc, err := net.FileListener(f); err == nil { + listeners[i] = pc + f.Close() + } + } + return listeners, nil +} + +// PacketConns returns a slice containing a net.PacketConn for each matching socket type +// passed to this process. +// +// The order of the file descriptors is preserved in the returned slice. +// Nil values are used to fill any gaps. For example if systemd were to return file descriptors +// corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn} +func PacketConns() ([]net.PacketConn, error) { + files := activation.Files(false) + conns := make([]net.PacketConn, len(files)) + + for i, f := range files { + if pc, err := net.FilePacketConn(f); err == nil { + conns[i] = pc + f.Close() + } + } + return conns, nil +} diff --git a/cmd/circologd/main.go b/cmd/circologd/main.go index 4063d8b..cd49548 100644 --- a/cmd/circologd/main.go +++ b/cmd/circologd/main.go @@ -59,7 +59,13 @@ func main() { server.SetHandler(handler) if syslogSocket.isSocketActivated { fmt.Printf("Binding to socket `%s` [syslog]\n", syslogSocket.String()) - server.Listen(syslogSocket.Listener) + if syslogSocket.Listener != nil { + fmt.Println("(stream)") + server.Listen(syslogSocket.Listener) + } else { + fmt.Println("(datagram)", syslogSocket.Conn) + server.ListenDgram(syslogSocket.Conn) + } } else { syslogSocketPath := syslogSocket.Path if syslogSocketPath != "" { diff --git a/cmd/circologd/sockets.go b/cmd/circologd/sockets.go index aa2919c..c475073 100644 --- a/cmd/circologd/sockets.go +++ b/cmd/circologd/sockets.go @@ -2,30 +2,26 @@ package main import ( "net" - - "github.com/coreos/go-systemd/activation" ) // SyslogSocket is a struct eventually containing a net.Listener // ready with messages, and a Path in case the Listener is not present. type SyslogSocket struct { Listener net.Listener + Conn net.PacketConn Path string isSocketActivated bool } +// Set from command-line func (s *SyslogSocket) Set(v string) error { - sock, err := s.getActivationSocket() - if err != nil { - return err - } - s.isSocketActivated = false - if sock != nil { - s.Listener = sock + err := s.getActivationSocket() + if err == nil && (s.Conn != nil || s.Listener != nil) { s.isSocketActivated = true - return nil } - s.Path = v + if !s.isSocketActivated { + s.Path = v + } return nil } @@ -36,13 +32,19 @@ func (s *SyslogSocket) String() string { return s.Path } -func (s *SyslogSocket) getActivationSocket() (net.Listener, error) { - listeners, err := activation.Listeners() +func (s *SyslogSocket) getActivationSocket() error { + conns, err := PacketConns() + if err == nil && len(conns) > 0 && conns[0] != nil { + s.Conn = conns[0] + return nil + } + listeners, err := Listeners() if err != nil { - return nil, err + return err } if len(listeners) == 0 { - return nil, nil + return nil } - return listeners[0], nil + s.Listener = listeners[0] + return nil } diff --git a/vendor/gopkg.in/mcuadros/go-syslog.v2 b/vendor/gopkg.in/mcuadros/go-syslog.v2 index 60a4bd3..166aad3 160000 --- a/vendor/gopkg.in/mcuadros/go-syslog.v2 +++ b/vendor/gopkg.in/mcuadros/go-syslog.v2 @@ -1 +1 @@ -Subproject commit 60a4bd305d7f4271670e66a1cd9c67cc361186b6 +Subproject commit 166aad3f993ce4a67bf486e62d637c834c8a8fe6