2023-12-15 16:35:41 +01:00
|
|
|
// SPDX-FileCopyrightText: 2023 Winni Neessen <wn@neessen.dev>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
2023-12-14 12:09:01 +01:00
|
|
|
package logranger
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ListenerType is an enumeration wrapper for the different listener types
|
|
|
|
type ListenerType uint
|
|
|
|
|
|
|
|
const (
|
2023-12-19 20:17:56 +01:00
|
|
|
// ListenerUnix is a constant of type ListenerType that represents a UNIX listener.
|
2023-12-14 12:09:01 +01:00
|
|
|
ListenerUnix ListenerType = iota
|
2023-12-19 20:17:56 +01:00
|
|
|
// ListenerTCP is a constant representing the type of listener that uses TCP protocol.
|
2023-12-14 12:09:01 +01:00
|
|
|
ListenerTCP
|
2023-12-19 20:17:56 +01:00
|
|
|
// ListenerTLS is a constant of type ListenerType that represents a TLS listener.
|
2023-12-14 12:09:01 +01:00
|
|
|
ListenerTLS
|
|
|
|
)
|
|
|
|
|
2023-12-19 20:17:56 +01:00
|
|
|
// NewListener initializes and returns a net.Listener based on the provided
|
|
|
|
// configuration. It takes a pointer to a Config struct as a parameter.
|
|
|
|
// Returns the net.Listener and an error if any occurred during initialization.
|
2023-12-14 12:09:01 +01:00
|
|
|
func NewListener(c *Config) (net.Listener, error) {
|
|
|
|
var l net.Listener
|
|
|
|
var lerr error
|
|
|
|
switch c.Listener.Type {
|
|
|
|
case ListenerUnix:
|
|
|
|
rua, err := net.ResolveUnixAddr("unix", c.Listener.ListenerUnix.Path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to resolve UNIX listener socket: %w", err)
|
|
|
|
}
|
|
|
|
l, lerr = net.Listen("unix", rua.String())
|
|
|
|
case ListenerTCP:
|
|
|
|
la := net.JoinHostPort(c.Listener.ListenerTCP.Addr, fmt.Sprintf("%d", c.Listener.ListenerTCP.Port))
|
|
|
|
l, lerr = net.Listen("tcp", la)
|
|
|
|
case ListenerTLS:
|
|
|
|
if c.Listener.ListenerTLS.CertPath == "" || c.Listener.ListenerTLS.KeyPath == "" {
|
|
|
|
return nil, ErrCertConfigEmpty
|
|
|
|
}
|
|
|
|
ce, err := tls.LoadX509KeyPair(c.Listener.ListenerTLS.CertPath, c.Listener.ListenerTLS.KeyPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load X509 certificate: %w", err)
|
|
|
|
}
|
2023-12-19 20:17:56 +01:00
|
|
|
la := net.JoinHostPort(c.Listener.ListenerTLS.Addr, fmt.Sprintf("%d", c.Listener.ListenerTLS.Port))
|
2023-12-14 12:09:01 +01:00
|
|
|
lc := &tls.Config{Certificates: []tls.Certificate{ce}}
|
|
|
|
l, lerr = tls.Listen("tcp", la, lc)
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("failed to initialize listener: unknown listener type in config")
|
|
|
|
}
|
|
|
|
if lerr != nil {
|
2023-12-22 15:31:44 +01:00
|
|
|
return nil, fmt.Errorf("failed to initialize listener: %w", lerr)
|
2023-12-14 12:09:01 +01:00
|
|
|
}
|
|
|
|
return l, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalString satisfies the fig.StringUnmarshaler interface for the ListenerType type
|
|
|
|
func (l *ListenerType) UnmarshalString(v string) error {
|
|
|
|
switch strings.ToLower(v) {
|
|
|
|
case "unix":
|
|
|
|
*l = ListenerUnix
|
|
|
|
case "tcp":
|
|
|
|
*l = ListenerTCP
|
|
|
|
case "tls":
|
|
|
|
*l = ListenerTLS
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unknown listener type: %s", v)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// String satisfies the fmt.Stringer interface for the ListenerType type
|
|
|
|
func (l ListenerType) String() string {
|
|
|
|
switch l {
|
|
|
|
case ListenerUnix:
|
|
|
|
return "UNIX listener"
|
|
|
|
case ListenerTCP:
|
|
|
|
return "TCP listener"
|
|
|
|
case ListenerTLS:
|
|
|
|
return "TLS listener"
|
|
|
|
default:
|
|
|
|
return "Unknown listener type"
|
|
|
|
}
|
|
|
|
}
|