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.
|
2024-03-21 20:22:33 +01:00
|
|
|
func NewListener(config *Config) (net.Listener, error) {
|
|
|
|
var listener net.Listener
|
|
|
|
var listenerErr error
|
|
|
|
switch config.Listener.Type {
|
2023-12-14 12:09:01 +01:00
|
|
|
case ListenerUnix:
|
2024-03-21 20:22:33 +01:00
|
|
|
resolveUnixAddr, err := net.ResolveUnixAddr("unix", config.Listener.ListenerUnix.Path)
|
2023-12-14 12:09:01 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to resolve UNIX listener socket: %w", err)
|
|
|
|
}
|
2024-03-21 20:22:33 +01:00
|
|
|
listener, listenerErr = net.Listen("unix", resolveUnixAddr.String())
|
2023-12-14 12:09:01 +01:00
|
|
|
case ListenerTCP:
|
2024-03-21 20:22:33 +01:00
|
|
|
listenAddr := net.JoinHostPort(config.Listener.ListenerTCP.Addr,
|
|
|
|
fmt.Sprintf("%d", config.Listener.ListenerTCP.Port))
|
|
|
|
listener, listenerErr = net.Listen("tcp", listenAddr)
|
2023-12-14 12:09:01 +01:00
|
|
|
case ListenerTLS:
|
2024-03-21 20:22:33 +01:00
|
|
|
if config.Listener.ListenerTLS.CertPath == "" || config.Listener.ListenerTLS.KeyPath == "" {
|
2023-12-14 12:09:01 +01:00
|
|
|
return nil, ErrCertConfigEmpty
|
|
|
|
}
|
2024-03-21 20:22:33 +01:00
|
|
|
cert, err := tls.LoadX509KeyPair(config.Listener.ListenerTLS.CertPath, config.Listener.ListenerTLS.KeyPath)
|
2023-12-14 12:09:01 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load X509 certificate: %w", err)
|
|
|
|
}
|
2024-03-21 20:22:33 +01:00
|
|
|
listenAddr := net.JoinHostPort(config.Listener.ListenerTLS.Addr, fmt.Sprintf("%d", config.Listener.ListenerTLS.Port))
|
|
|
|
listenConf := &tls.Config{Certificates: []tls.Certificate{cert}}
|
|
|
|
listener, listenerErr = tls.Listen("tcp", listenAddr, listenConf)
|
2023-12-14 12:09:01 +01:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("failed to initialize listener: unknown listener type in config")
|
|
|
|
}
|
2024-03-21 20:22:33 +01:00
|
|
|
if listenerErr != nil {
|
|
|
|
return nil, fmt.Errorf("failed to initialize listener: %w", listenerErr)
|
2023-12-14 12:09:01 +01:00
|
|
|
}
|
2024-03-21 20:22:33 +01:00
|
|
|
return listener, nil
|
2023-12-14 12:09:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalString satisfies the fig.StringUnmarshaler interface for the ListenerType type
|
2024-03-21 20:22:33 +01:00
|
|
|
func (l *ListenerType) UnmarshalString(value string) error {
|
|
|
|
switch strings.ToLower(value) {
|
2023-12-14 12:09:01 +01:00
|
|
|
case "unix":
|
|
|
|
*l = ListenerUnix
|
|
|
|
case "tcp":
|
|
|
|
*l = ListenerTCP
|
|
|
|
case "tls":
|
|
|
|
*l = ListenerTLS
|
|
|
|
default:
|
2024-03-21 20:22:33 +01:00
|
|
|
return fmt.Errorf("unknown listener type: %s", value)
|
2023-12-14 12:09:01 +01:00
|
|
|
}
|
|
|
|
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"
|
|
|
|
}
|
|
|
|
}
|