Documentation
¶
Overview ¶
Package config provides configuration structures for creating socket clients and servers.
This package offers a declarative configuration approach for socket connections, allowing you to define client and server settings before instantiation.
It supports all socket types through the NetworkProtocol interface:
- TCP: Connection-oriented, reliable network sockets
- UDP: Connectionless, fast network sockets
- Unix: Connection-oriented IPC via filesystem sockets
- Unixgram: Connectionless IPC via filesystem sockets
The configuration structs are typically used in scenarios where socket parameters are loaded from external sources (config files, environment variables, etc.) and need to be validated and instantiated separately.
See github.com/nabbar/golib/socket/client for client implementations. See github.com/nabbar/golib/socket/server for server implementations. See github.com/nabbar/golib/network/protocol for supported protocols.
Package config provides declarative configuration structures for socket clients and servers.
Overview ¶
This package implements a configuration-first approach to socket programming, allowing you to define connection parameters before instantiation. It's designed for scenarios where socket settings are loaded from external sources (configuration files, environment variables, databases) and need validation before use.
The package supports all common socket types through a unified interface:
- TCP: Reliable, connection-oriented network sockets
- UDP: Fast, connectionless network sockets
- Unix: Connection-oriented inter-process communication via filesystem sockets
- Unixgram: Connectionless inter-process communication via filesystem sockets
Design Philosophy ¶
The package follows these design principles:
1. Configuration Separation: Socket parameters are defined independently from socket instances, enabling validation before connection attempts. This separation allows for early detection of configuration errors without allocating network resources.
2. Declarative API: Configuration uses simple struct field assignments rather than complex builder patterns or method chaining. This makes configurations easy to serialize, deserialize, and manipulate programmatically.
3. Fail-Fast Validation: The Validate() methods catch configuration errors early, before network operations are attempted. Validation includes DNS resolution, address format checking, and platform compatibility verification.
4. Platform Awareness: Built-in checks for platform-specific limitations (e.g., Unix sockets on Windows). The package provides clear error messages when attempting to use unsupported features on incompatible platforms.
5. Security by Default: TLS/SSL configuration is validated to ensure proper certificate handling and protocol restrictions. The package enforces that TLS is only used with appropriate protocols and that all required parameters are present.
Key Features ¶
Protocol Flexibility: Single configuration API supports TCP, UDP, Unix, and Unixgram sockets through the NetworkProtocol interface. This unification simplifies code that needs to support multiple transport types.
TLS Support: First-class TLS/SSL configuration for TCP connections with certificate validation and server name verification. Supports both client and server TLS with customizable cipher suites and protocol versions.
Unix Socket Permissions: Fine-grained control over Unix socket file permissions and group ownership for security-sensitive IPC. Allows specifying both file mode bits and group ownership to implement proper access control.
Connection Management: Configurable idle timeouts for connection-oriented protocols to prevent resource exhaustion from stale connections.
Validation Guarantees: Comprehensive validation catches address format errors, protocol mismatches, platform incompatibilities, and TLS configuration issues before any network operations are attempted.
Architecture ¶
The package consists of two main configuration structures:
┌─────────────────────────────────────────────────────────────┐
│ socket/config │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Client │ │ Server │ │
│ ├──────────────┤ ├──────────────┤ │
│ │ Network │ │ Network │ │
│ │ Address │ │ Address │ │
│ │ TLS │ │ PermFile │ │
│ │ │ │ GroupPerm │ │
│ │ + Validate() │ │ ConIdleTimeout│ │
│ └──────────────┘ │ TLS │ │
│ │ │ │
│ │ + Validate() │ │
│ │ + DefaultTLS()│ │
│ │ + GetTLS() │ │
│ └──────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Error Types │ │
│ ├────────────────────────────────────────────┤ │
│ │ ErrInvalidProtocol │ │
│ │ ErrInvalidTLSConfig │ │
│ │ ErrInvalidGroup │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │
│ │
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ socket/client │ │ socket/server │
│ implementations │ │ implementations │
└────────────────────┘ └────────────────────┘
Configuration flows from external sources → config structs → validation → socket implementations. This separation ensures that invalid configurations are caught before any network resources are allocated.
Key Features ¶
Protocol Flexibility: Single configuration API supports TCP, UDP, Unix, and Unixgram sockets through the NetworkProtocol interface.
TLS Support: First-class TLS/SSL configuration for TCP connections with certificate validation and server name verification.
Unix Socket Permissions: Fine-grained control over Unix socket file permissions and group ownership for security-sensitive IPC.
Connection Management: Configurable idle timeouts for connection-oriented protocols to prevent resource exhaustion.
Validation Guarantees: Comprehensive validation catches address format errors, protocol mismatches, platform incompatibilities, and TLS configuration issues.
Limitations ¶
1. Platform-Specific Features: Unix domain sockets are not available on Windows. Configuration validation will return ErrInvalidProtocol on unsupported platforms.
2. TLS Protocol Restrictions: TLS/SSL is only supported for TCP-based protocols. UDP and Unix sockets cannot use TLS through this package.
3. No Dynamic Reconfiguration: Once a socket is created from a configuration, changing the configuration does not affect the existing socket. You must create a new socket instance.
4. Group Permission Limits: Unix socket group IDs are limited to MaxGID (32767) for portability across Unix-like systems.
5. No IPv6 Scope IDs: While IPv6 addresses are supported, zone/scope IDs in link-local addresses may have platform-specific behavior.
Performance Considerations ¶
The configuration structures are designed for infrequent creation (e.g., application startup) rather than high-frequency operations. Validation involves DNS resolution and filesystem checks, which may block.
Performance characteristics:
Structure Creation: < 100µs (simple struct initialization) TCP Validation: < 1ms average (includes DNS resolution) UDP Validation: < 1ms average (includes DNS resolution) Unix Validation: < 100µs (no DNS, just address checks) Structure Copy: < 10µs (small memory footprint)
For hot-path operations:
- Cache validated configurations rather than re-validating on each use
- Create socket instances once at startup and reuse them throughout the application lifecycle
- Avoid calling Validate() in request handling loops or performance-critical paths
- Validation may block for DNS resolution, so perform it asynchronously if needed
The structs are small (< 100 bytes) and safe to copy by value. However, they contain interface fields (TLS.Config) that may reference larger objects. Copying the struct creates a shallow copy that shares these referenced objects.
Use Cases ¶
Configuration File Loading:
Load socket parameters from YAML, JSON, or TOML files and validate them before starting services. This catches configuration errors at startup rather than during operation.
Environment-Based Configuration:
Read socket settings from environment variables (12-factor app pattern) and create properly validated socket instances for different deployment environments.
Dynamic Service Discovery:
Receive socket addresses from service discovery systems (Consul, etcd) and validate them before establishing connections.
Multi-Protocol Services:
Configure services to listen on multiple socket types simultaneously (TCP for network access, Unix sockets for local IPC) using a unified configuration format.
Secure Service Communication:
Define TLS/SSL parameters for encrypted client-server communication with proper certificate validation and server name verification.
Error Handling ¶
All validation methods return typed errors that can be checked:
if err := cfg.Validate(); err != nil {
switch {
case errors.Is(err, config.ErrInvalidProtocol):
// Handle unsupported protocol
case errors.Is(err, config.ErrInvalidTLSConfig):
// Handle TLS configuration error
case errors.Is(err, config.ErrInvalidGroup):
// Handle group permission error
default:
// Handle address resolution or other errors
}
}
Address resolution errors come from the standard net package and preserve the original error information for debugging.
Thread Safety ¶
Configuration structures are safe to read from multiple goroutines after creation, but must not be modified concurrently. If you need to share configurations across goroutines, either:
- Create separate copies for each goroutine (structs are small)
- Protect shared instances with sync.RWMutex
- Use immutable patterns (create new configs instead of modifying)
The Server.DefaultTLS() and Server.GetTLS() methods are not thread-safe and should not be called concurrently with other operations on the same instance.
Examples ¶
See the package examples for detailed usage patterns:
- Basic TCP client and server configuration
- Unix socket configuration with permissions
- TLS-enabled secure connections
- Configuration loading from external sources
- Error handling and validation
Example (BasicTCPClient) ¶
Example_basicTCPClient demonstrates the simplest TCP client configuration.
This example shows minimal configuration for connecting to a TCP server.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a basic TCP client configuration
cfg := config.Client{
Network: libptc.NetworkTCP,
Address: "localhost:8080",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("TCP client configuration validated successfully")
}
Output: TCP client configuration validated successfully
Example (BasicTCPServer) ¶
Example_basicTCPServer demonstrates the simplest TCP server configuration.
This example shows minimal configuration for a TCP server listening on all interfaces.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a basic TCP server configuration
cfg := config.Server{
Network: libptc.NetworkTCP,
Address: ":8080",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("TCP server configuration validated successfully")
}
Output: TCP server configuration validated successfully
Example (BasicUDPClient) ¶
Example_basicUDPClient demonstrates UDP client configuration.
This example shows how to configure a UDP client for connectionless communication.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a UDP client configuration
cfg := config.Client{
Network: libptc.NetworkUDP,
Address: "localhost:9000",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("UDP client configuration validated successfully")
}
Output: UDP client configuration validated successfully
Example (BasicUDPServer) ¶
Example_basicUDPServer demonstrates UDP server configuration.
This example shows how to configure a UDP server for datagram handling.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a UDP server configuration
cfg := config.Server{
Network: libptc.NetworkUDP,
Address: ":9000",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("UDP server configuration validated successfully")
}
Output: UDP server configuration validated successfully
Example (ConfigurationFromEnvironment) ¶
Example_configurationFromEnvironment demonstrates loading configuration from environment.
This example shows a common pattern for 12-factor apps.
package main
import (
"fmt"
"os"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Simulate reading from environment
network := os.Getenv("SOCKET_NETWORK")
if network == "" {
network = "tcp" // Default
}
address := os.Getenv("SOCKET_ADDRESS")
if address == "" {
address = ":8080" // Default
}
// Parse network protocol
var proto libptc.NetworkProtocol
switch network {
case "tcp":
proto = libptc.NetworkTCP
case "udp":
proto = libptc.NetworkUDP
case "unix":
proto = libptc.NetworkUnix
default:
fmt.Printf("Unknown network type: %s\n", network)
return
}
// Create configuration
cfg := config.Server{
Network: proto,
Address: address,
}
// Validate before use
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Printf("Server configured for %s on %s\n", network, address)
}
Output: Server configured for tcp on :8080
Example (DualStackServer) ¶
Example_dualStackServer demonstrates configuring a dual-stack (IPv4 + IPv6) server.
This example shows how to listen on both IPv4 and IPv6.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Dual-stack server (listens on both IPv4 and IPv6)
cfg := config.Server{
Network: libptc.NetworkTCP,
Address: ":8080", // Binds to both [::]:8080 and 0.0.0.0:8080
}
if err := cfg.Validate(); err != nil {
fmt.Printf("Dual-stack configuration error: %v\n", err)
return
}
fmt.Println("Dual-stack server configuration validated")
}
Output: Dual-stack server configuration validated
Example (GroupPermissionValidation) ¶
Example_groupPermissionValidation demonstrates Unix socket group permission validation.
This example shows how to configure and validate group ownership.
package main
import (
"fmt"
"runtime"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
if runtime.GOOS == "windows" {
fmt.Println("Unix sockets not available on Windows")
return
}
// Valid group permission
validCfg := config.Server{
Network: libptc.NetworkUnix,
Address: "/tmp/app.sock",
PermFile: 0660,
GroupPerm: 1000, // Valid group ID
}
if err := validCfg.Validate(); err != nil {
fmt.Printf("Unexpected error: %v\n", err)
return
}
// Invalid group permission (exceeds MaxGID)
invalidCfg := config.Server{
Network: libptc.NetworkUnix,
Address: "/tmp/app.sock",
PermFile: 0660,
GroupPerm: 99999, // Exceeds MaxGID
}
if err := invalidCfg.Validate(); err != nil {
fmt.Println("Group permission validation failed as expected")
return
}
fmt.Println("Valid group permission configured")
}
Output: Group permission validation failed as expected
Example (InvalidAddress) ¶
Example_invalidAddress demonstrates error handling for invalid addresses.
This example shows how validation catches malformed addresses.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a client with invalid address format
cfg := config.Client{
Network: libptc.NetworkTCP,
Address: "invalid-address-without-port",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Println("Address validation failed as expected")
return
}
fmt.Println("This should not be reached")
}
Output: Address validation failed as expected
Example (InvalidProtocol) ¶
Example_invalidProtocol demonstrates error handling for invalid protocols.
This example shows how to detect and handle protocol validation errors.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a client with zero-value protocol (invalid)
cfg := config.Client{
Network: libptc.NetworkProtocol(0),
Address: "localhost:8080",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Println("Invalid protocol error detected")
return
}
fmt.Println("This should not be reached")
}
Output: Invalid protocol error detected
Example (Ipv6Configuration) ¶
Example_ipv6Configuration demonstrates configuring IPv6 sockets.
This example shows how to configure servers for IPv6 networks.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// IPv6-specific server
cfg := config.Server{
Network: libptc.NetworkTCP6,
Address: "[::1]:8080", // IPv6 loopback
}
if err := cfg.Validate(); err != nil {
fmt.Printf("IPv6 configuration error: %v\n", err)
return
}
fmt.Println("IPv6 server configuration validated")
}
Output: IPv6 server configuration validated
Example (MultipleServers) ¶
Example_multipleServers demonstrates configuring multiple server types.
This example shows how to set up a service that listens on both network and Unix sockets.
package main
import (
"fmt"
"runtime"
libdur "github.com/nabbar/golib/duration"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Network server for remote access
tcpCfg := config.Server{
Network: libptc.NetworkTCP,
Address: ":8080",
ConIdleTimeout: libdur.Minutes(10),
}
if err := tcpCfg.Validate(); err != nil {
fmt.Printf("TCP configuration error: %v\n", err)
return
}
// Unix socket for local IPC (if not on Windows)
var unixCfg *config.Server
if runtime.GOOS != "windows" {
unixCfg = &config.Server{
Network: libptc.NetworkUnix,
Address: "/tmp/app.sock",
PermFile: 0660,
}
if err := unixCfg.Validate(); err != nil {
fmt.Printf("Unix socket configuration error: %v\n", err)
return
}
}
fmt.Println("Multiple server configurations validated")
if unixCfg != nil {
fmt.Println("Both TCP and Unix socket servers ready")
} else {
fmt.Println("TCP server ready (Unix socket not available on this platform)")
}
}
Output: Multiple server configurations validated Both TCP and Unix socket servers ready
Example (ServerWithIdleTimeout) ¶
Example_serverWithIdleTimeout demonstrates server configuration with connection timeout.
This example shows how to configure automatic disconnection of idle connections.
package main
import (
"fmt"
libdur "github.com/nabbar/golib/duration"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
// Create a server with idle timeout
cfg := config.Server{
Network: libptc.NetworkTCP,
Address: ":8080",
ConIdleTimeout: libdur.Minutes(5), // Close idle connections after 5 minutes
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("Server with idle timeout configured successfully")
}
Output: Server with idle timeout configured successfully
Example (UnixSocketClient) ¶
Example_unixSocketClient demonstrates Unix domain socket client configuration.
This example shows how to configure a client for Unix socket IPC. Note: Unix sockets are not available on Windows.
package main
import (
"fmt"
"runtime"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
if runtime.GOOS == "windows" {
fmt.Println("Unix sockets not available on Windows")
return
}
// Create a Unix socket client configuration
cfg := config.Client{
Network: libptc.NetworkUnix,
Address: "/tmp/app.sock",
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("Unix socket client configuration validated successfully")
}
Output: Unix socket client configuration validated successfully
Example (UnixSocketServer) ¶
Example_unixSocketServer demonstrates Unix domain socket server configuration.
This example shows how to configure a Unix socket server with file permissions. Note: Unix sockets are not available on Windows.
package main
import (
"fmt"
"runtime"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
if runtime.GOOS == "windows" {
fmt.Println("Unix sockets not available on Windows")
return
}
// Create a Unix socket server configuration with permissions
cfg := config.Server{
Network: libptc.NetworkUnix,
Address: "/tmp/app.sock",
PermFile: 0660, // Owner and group can read/write
GroupPerm: -1, // Use current process group
}
// Validate the configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("Invalid configuration: %v\n", err)
return
}
fmt.Println("Unix socket server configuration validated successfully")
}
Output: Unix socket server configuration validated successfully
Example (ValidationBeforeUse) ¶
Example_validationBeforeUse demonstrates best practices for configuration validation.
This example shows the recommended pattern of validate-then-use.
package main
import (
"fmt"
"github.com/nabbar/golib/socket/config"
libptc "github.com/nabbar/golib/network/protocol"
)
func main() {
configs := []config.Server{
{Network: libptc.NetworkTCP, Address: ":8080"},
{Network: libptc.NetworkTCP, Address: ":8081"},
{Network: libptc.NetworkUDP, Address: ":9000"},
}
// Validate all configurations before starting any servers
for i, cfg := range configs {
if err := cfg.Validate(); err != nil {
fmt.Printf("Configuration %d invalid: %v\n", i, err)
return
}
}
fmt.Printf("All %d configurations validated successfully\n", len(configs))
}
Output: All 3 configurations validated successfully
Index ¶
Examples ¶
- Package (BasicTCPClient)
- Package (BasicTCPServer)
- Package (BasicUDPClient)
- Package (BasicUDPServer)
- Package (ConfigurationFromEnvironment)
- Package (DualStackServer)
- Package (GroupPermissionValidation)
- Package (InvalidAddress)
- Package (InvalidProtocol)
- Package (Ipv6Configuration)
- Package (MultipleServers)
- Package (ServerWithIdleTimeout)
- Package (UnixSocketClient)
- Package (UnixSocketServer)
- Package (ValidationBeforeUse)
Constants ¶
const MaxGID = 32767
MaxGID defines the maximum allowed Unix group ID for socket file ownership.
This value represents the upper limit for the Server.GroupPerm field. Group IDs above this threshold will cause Server.Validate() to return ErrInvalidGroup.
The value 32767 is chosen as a conservative limit that is compatible with most Unix-like systems, where traditional group IDs are typically stored as signed 16-bit integers.
Variables ¶
var ( // ErrInvalidProtocol indicates that an unsupported or invalid network protocol was specified. // // This error is returned when: // - The Network field contains an unrecognized protocol // - Unix domain sockets are used on Windows (not supported) // - The protocol is incompatible with the requested operation // // Valid protocols are defined in github.com/nabbar/golib/network/protocol: // - NetworkTCP, NetworkTCP4, NetworkTCP6 // - NetworkUDP, NetworkUDP4, NetworkUDP6 // - NetworkUnix, NetworkUnixGram (not available on Windows) ErrInvalidProtocol = errors.New("invalid protocol") // ErrInvalidTLSConfig indicates that TLS/SSL configuration is invalid or incomplete. // // This error is returned when: // - TLS is enabled but Config.New() returns nil // - TLS is enabled but ServerName is empty (client only) // - TLS configuration lacks required certificate pairs (server only) // - TLS is enabled for non-TCP protocols (UDP, Unix sockets) // // TLS is only supported for TCP-based connections: // - Client: Requires valid Config and ServerName // - Server: Requires valid Config with at least one certificate pair ErrInvalidTLSConfig = errors.New("invalid TLS config") // ErrInvalidGroup indicates that the Unix group ID exceeds the maximum allowed value. // // This error is returned when: // - Server.GroupPerm is greater than MaxGID (32767) // // Valid group ID values: // - -1: Use the process's current group (default) // - 0 to MaxGID: Specific group ID // // This validation only applies to Unix domain socket servers. ErrInvalidGroup = errors.New("invalid unix group for socket group permission") )
Functions ¶
This section is empty.
Types ¶
type Client ¶ added in v1.19.0
type Client struct {
// Network specifies the transport protocol to use for the connection.
//
// Supported values:
// - NetworkTCP: TCP/IP network socket (e.g., "localhost:8080", "192.168.1.1:9000")
// - NetworkUDP: UDP/IP network socket (e.g., "localhost:8080", "192.168.1.1:9000")
// - NetworkUnix: Unix domain stream socket (e.g., "/tmp/app.sock", "./socket")
// - NetworkUnixGram: Unix domain datagram socket (e.g., "/tmp/app.sock")
//
// The protocol determines both the transport layer and the addressing scheme.
// See github.com/nabbar/golib/network/protocol for protocol definitions.
Network libptc.NetworkProtocol `json:"network" yaml:"network" toml:"network" mapstructure:"network"`
// Address specifies the destination to connect to.
//
// Format depends on the Network protocol:
// - TCP/UDP: "host:port" (e.g., "localhost:8080", "192.168.1.1:9000")
// - Unix/Unixgram: file path (e.g., "/tmp/app.sock", "./socket")
//
// For network protocols (TCP/UDP):
// - Use "host:port" format
// - Host can be hostname, IPv4, or IPv6 address
// - Port must be in range 1-65535
//
// For Unix domain sockets:
// - Use absolute or relative file path
// - Path must be accessible (read/write permissions)
// - Maximum path length depends on OS (typically 108 bytes)
//
// Empty address will cause New() to return an error.
Address string `json:"address" yaml:"address" toml:"address" mapstructure:"address"`
// TLS provides Transport Layer Security configuration for the client.
//
// TLS is only supported for TCP-based protocols (NetworkTCP, NetworkTCP4, NetworkTCP6).
// Attempting to enable TLS for other protocols will cause Validate() to return ErrInvalidTLSConfig.
//
// Fields:
// - Enabled: Set to true to enable TLS/SSL encryption
// - Config: Certificate configuration from github.com/nabbar/golib/certificates
// - ServerName: Server hostname for certificate validation (required when Enabled is true)
//
// Example:
// cfg := config.Client{
// Network: protocol.NetworkTCP,
// Address: "secure.example.com:443",
// TLS: struct{
// Enabled: true,
// Config: tlsConfig,
// ServerName: "secure.example.com",
// },
// }
//
// The Config must provide valid certificates and the ServerName must match
// the server's certificate for successful validation.
TLS TLSClient `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
// contains filtered or unexported fields
}
Client defines the configuration for creating a socket client.
This structure provides a declarative way to specify client connection parameters before instantiation. It's particularly useful when loading configuration from external sources or when you need to validate settings before connecting.
Example usage:
// TCP client configuration
cfg := config.Client{
Network: protocol.NetworkTCP,
Address: "localhost:8080",
}
client, err := cfg.New()
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Unix socket client configuration
cfg := config.Client{
Network: protocol.NetworkUnix,
Address: "/tmp/app.sock",
}
The New() method validates the configuration and returns an appropriate client implementation based on the network protocol.
See github.com/nabbar/golib/socket/client for more client examples.
func (*Client) DefaultTLS ¶ added in v1.19.0
DefaultTLS sets a default TLS configuration that will be merged with TLS.Config.
This method is useful when you want to provide fallback or base TLS settings that will be combined with the specific configuration in TLS.Config.
The provided configuration will be stored and used by GetTLS() to create the final TLS configuration via Config.NewFrom().
Parameters:
- t: Base TLS configuration from github.com/nabbar/golib/certificates
Example:
srv := &config.Server{...}
srv.DefaultTLS(baseTLSConfig)
// Later, GetTLS() will merge TLS.Config with baseTLSConfig
See GetTLS() for how this default is applied.
func (*Client) GetTLS ¶ added in v1.19.0
GetTLS returns the TLS configuration with defaults applied.
This method checks if TLS is enabled and returns the merged TLS configuration by combining TLS.Config with the default set via DefaultTLS().
Returns:
- bool: true if TLS is enabled, false otherwise
- TLSConfig: The merged TLS configuration, or nil if TLS is disabled
The returned configuration is created via Config.NewFrom(defTls), which merges the specific TLS.Config settings with the default configuration.
Example:
if enabled, tlsConfig := srv.GetTLS(); enabled {
// Use tlsConfig for TLS connections
}
See DefaultTLS() for setting the default configuration.
func (*Client) Validate ¶ added in v1.19.0
Validate checks the client configuration for correctness and compatibility.
This method performs several validation checks:
- Verifies that the network protocol is supported
- Validates address format for the specified protocol
- Checks platform compatibility (Unix sockets not supported on Windows)
- Validates TLS configuration if enabled
Returns an error if:
- The protocol is unsupported (returns ErrInvalidProtocol)
- The address format is invalid for the protocol
- Unix sockets are used on Windows (returns ErrInvalidProtocol)
- TLS is enabled but improperly configured (returns ErrInvalidTLSConfig)
- TLS is enabled for non-TCP protocols (returns ErrInvalidTLSConfig)
TLS-specific validation ensures:
- Config.New() returns a valid TLS configuration
- ServerName is specified
- Config.TLS(ServerName) returns a valid tls.Config
Example:
cfg := config.Client{Network: protocol.NetworkTCP, Address: "localhost:8080"}
if err := cfg.Validate(); err != nil {
log.Fatal("Invalid configuration:", err)
}
type Server ¶ added in v1.19.0
type Server struct {
// Network specifies the transport protocol for the server.
//
// Supported values:
// - NetworkTCP: TCP/IP server (e.g., ":8080", "0.0.0.0:8080")
// - NetworkUDP: UDP/IP server (e.g., ":8080", "0.0.0.0:8080")
// - NetworkUnix: Unix domain stream server (e.g., "/tmp/app.sock")
// - NetworkUnixGram: Unix domain datagram server (e.g., "/tmp/app.sock")
//
// The protocol determines both the transport layer and addressing:
// - TCP: Connection-oriented, reliable, multiple concurrent clients
// - UDP: Connectionless, fast, stateless datagram handling
// - Unix: IPC stream sockets, connection-oriented, file permissions
// - Unixgram: IPC datagram sockets, connectionless, file permissions
//
// See github.com/nabbar/golib/network/protocol for protocol definitions.
// See github.com/nabbar/golib/socket/server for implementation details.
Network libptc.NetworkProtocol `json:"network" yaml:"network" toml:"network" mapstructure:"network"`
// Address specifies where the server should listen.
//
// Format depends on the Network protocol:
// - TCP/UDP: "[host]:port" (e.g., "0:8080", "0.0.0.0:8080", "localhost:9000")
// - Unix/Unixgram: file path (e.g., "/tmp/app.sock", "./socket")
//
// For network protocols (TCP/UDP):
// - Use ":port" to listen on all interfaces
// - Use "host:port" to listen on specific interface
// - Port must be in range 1-65535
// - Ports < 1024 require elevated privileges
//
// For Unix domain sockets:
// - Use absolute or relative file path
// - File must not exist (will be created)
// - Directory must be writable
// - File is removed on server shutdown
// - Maximum path length depends on OS (typically 108 bytes)
//
// Empty address will cause New() to return an error.
Address string `json:"address" yaml:"address" toml:"address" mapstructure:"address"`
// PermFile specifies file permissions for Unix domain socket files.
//
// This field is only used for Unix and Unixgram protocols and is ignored
// for TCP/UDP servers.
//
// Common permission values:
// - 0600: Owner read/write only (most secure)
// - 0660: Owner and group read/write
// - 0666: All users read/write (least secure, not recommended)
//
// The permissions control who can connect to the socket:
// - Read permission: Required to connect
// - Write permission: Required to send data
//
// If set to 0 (zero), a default permission of 0770 is applied.
//
// Example:
// PermFile: 0600 // Only process owner can connect
// PermFile: 0660 // Owner and group members can connect
//
// See os.FileMode for permission representation.
PermFile libprm.Perm `json:"perm-file" yaml:"perm-file" toml:"perm-file" mapstructure:"perm-file"`
// GroupPerm specifies the group ownership for Unix domain socket files.
//
// This field is only used for Unix and Unixgram protocols and is ignored
// for TCP/UDP servers.
//
// The value is a numeric group ID (GID) that will own the socket file.
// This allows group-based access control in combination with PermFile.
//
// Special values:
// - -1: Use the process's current group (default)
// - 0-32767: Specific group ID
// - >32767: Will cause New() to return ErrInvalidGroup
//
// The process must have permission to change the group ownership,
// either by:
// - Running as root
// - Being a member of the target group
//
// Example:
// GroupPerm: -1 // Use current process group
// GroupPerm: 1000 // Set to group 1000
//
// Combined with PermFile 0660, this enables group-based access control.
GroupPerm int32 `json:"group-perm" yaml:"group-perm" toml:"group-perm" mapstructure:"group-perm"`
// ConIdleTimeout specifies the maximum duration a connection can remain idle.
//
// This field is only used for connection-oriented protocols (TCP, Unix).
// It is ignored for connectionless protocols (UDP, Unixgram).
//
// When set to a positive duration:
// - Connections with no activity for this duration will be closed
// - Helps prevent resource exhaustion from stale connections
// - Each connection has its own independent timeout
//
// Special values:
// - 0: No timeout, connections remain open indefinitely (default)
// - Negative: Invalid, treated as 0
//
// Example:
// ConIdleTimeout: 5 * time.Minute // Close idle connections after 5 minutes
// ConIdleTimeout: 0 // Never timeout
//
// Note: This timeout is independent of read/write deadlines that may be
// set on individual operations.
ConIdleTimeout libdur.Duration `json:"con-idle-timeout" yaml:"con-idle-timeout" toml:"con-idle-timeout" mapstructure:"con-idle-timeout"`
// TLS provides Transport Layer Security configuration for the server.
//
// TLS is only supported for TCP-based protocols (NetworkTCP, NetworkTCP4, NetworkTCP6).
// Attempting to enable TLS for other protocols will cause Validate() to return ErrInvalidTLSConfig.
//
// Fields:
// - Enable: Set to true to enable TLS/SSL encryption
// - Config: Certificate configuration from github.com/nabbar/golib/certificates
//
// Example:
// cfg := config.Server{
// Network: protocol.NetworkTCP,
// Address: ":8443",
// TLS: struct{
// Enable: true,
// Config: tlsConfig,
// },
// }
//
// When TLS is enabled:
// - Config must provide at least one valid certificate pair
// - All client connections will use TLS encryption
// - Clients must use TLS to connect
//
// Use DefaultTLS() to set a fallback TLS configuration that will be used
// if Config doesn't provide all necessary settings.
TLS TLSServer `json:"tls" yaml:"tls" toml:"tls" mapstructure:"tls"`
// contains filtered or unexported fields
}
Server defines the configuration for creating a socket server.
This structure provides a declarative way to specify server parameters before instantiation. It's particularly useful when loading configuration from external sources or when you need to validate settings before starting.
The server supports all socket types through the NetworkProtocol interface:
- TCP: Connection-oriented network server with multiple concurrent clients
- UDP: Connectionless network server with datagram handling
- Unix: Connection-oriented IPC server via filesystem sockets
- Unixgram: Connectionless IPC server via filesystem sockets
Example TCP server:
cfg := config.Server{
Network: protocol.NetworkTCP,
Address: ":8080",
}
if err := cfg.Validate(); err != nil {
log.Fatal(err)
}
Example Unix socket server with permissions:
cfg := config.Server{
Network: protocol.NetworkUnix,
Address: "/tmp/app.sock",
PermFile: 0660,
GroupPerm: 1000,
}
See github.com/nabbar/golib/socket/server for server implementations.
func (*Server) DefaultTLS ¶ added in v1.19.0
DefaultTLS sets a default TLS configuration that will be merged with TLS.Config.
This method is useful when you want to provide fallback or base TLS settings that will be combined with the specific configuration in TLS.Config.
The provided configuration will be stored and used by GetTLS() to create the final TLS configuration via Config.NewFrom().
Parameters:
- t: Base TLS configuration from github.com/nabbar/golib/certificates
Example:
srv := &config.Server{...}
srv.DefaultTLS(baseTLSConfig)
// Later, GetTLS() will merge TLS.Config with baseTLSConfig
See GetTLS() for how this default is applied.
func (*Server) GetTLS ¶ added in v1.19.0
GetTLS returns the TLS configuration with defaults applied.
This method checks if TLS is enabled and returns the merged TLS configuration by combining TLS.Config with the default set via DefaultTLS().
Returns:
- bool: true if TLS is enabled, false otherwise
- TLSConfig: The merged TLS configuration, or nil if TLS is disabled
The returned configuration is created via Config.NewFrom(defTls), which merges the specific TLS.Config settings with the default configuration.
Example:
if enabled, tlsConfig := srv.GetTLS(); enabled {
// Use tlsConfig for TLS connections
}
See DefaultTLS() for setting the default configuration.
func (*Server) Validate ¶ added in v1.19.0
Validate checks the server configuration for correctness and compatibility.
This method performs several validation checks:
- Verifies that the network protocol is supported
- Validates address format for the specified protocol
- Checks platform compatibility (Unix sockets not supported on Windows)
- Validates group permissions for Unix sockets
- Validates TLS configuration if enabled
Returns an error if:
- The protocol is unsupported (returns ErrInvalidProtocol)
- The address format is invalid for the protocol
- Unix sockets are used on Windows (returns ErrInvalidProtocol)
- GroupPerm exceeds MaxGID (returns ErrInvalidGroup)
- TLS is enabled but improperly configured (returns ErrInvalidTLSConfig)
- TLS is enabled for non-TCP protocols (returns ErrInvalidTLSConfig)
TLS-specific validation ensures:
- Config.New() returns a valid TLS configuration
- Config.LenCertificatePair() returns at least 1 certificate pair
Example:
cfg := config.Server{Network: protocol.NetworkTCP, Address: ":8080"}
if err := cfg.Validate(); err != nil {
log.Fatal("Invalid configuration:", err)
}
type TLSClient ¶ added in v1.19.0
type TLSClient struct {
Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled" mapstructure:"enabled"`
Config libtls.Config `json:"config" yaml:"config" toml:"config" mapstructure:"config"`
ServerName string `json:"server-name" yaml:"server-name" toml:"server-name" mapstructure:"server-name"`
}
TLSClient holds TLS configuration for client connections.
This structure is embedded in the Client configuration to enable TLS/SSL encryption for TCP-based client connections.
Fields:
- Enabled: Set to true to enable TLS encryption
- Config: Certificate configuration from github.com/nabbar/golib/certificates
- ServerName: Server hostname for certificate validation (required when Enabled is true)
The ServerName field is used for SNI (Server Name Indication) and certificate hostname verification. It must match the server's certificate common name or one of its Subject Alternative Names.
type TLSServer ¶ added in v1.19.0
type TLSServer struct {
Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled" mapstructure:"enabled"`
Config libtls.Config `json:"config" yaml:"config" toml:"config" mapstructure:"config"`
}
TLSServer holds TLS configuration for server connections.
This structure is embedded in the Server configuration to enable TLS/SSL encryption for TCP-based server connections.
Fields:
- Enabled: Set to true to enable TLS encryption
- Config: Certificate configuration from github.com/nabbar/golib/certificates
When TLS is enabled, the Config must provide at least one valid certificate pair (certificate and private key). All client connections will be required to use TLS encryption.