- Corrected the total header size from 273 to 274 bytes.
- Improved documentation for `StreamRequestHeader` and `ConnectionManager` types, including method descriptions.
- Added details on TCP and UDP functions, as well as connection management and ALPN protocol usage.
- Added information about the loading page (HTML + JS + CSS) and the SSE endpoint for wake events.
- Clarified the health monitor implementation and readiness tracking in the architecture overview.
- Correct state machine syntax.
- Introduced a new `update-wiki` script to automate the synchronization of implementation documentation from the repository to the wiki.
- Added necessary configuration files including `package.json`, `tsconfig.json`, and `.gitignore` for the new script.
- Updated the Makefile to include a target for running the `update-wiki` script.
- Correct BaseContext nil check in Context() method
- Move NewMonitor from monitor.go to new.go
- Export ErrDockerHealthCheckFailedTooManyTimes and add ErrDockerHealthCheckNotAvailable
- Return ErrDockerHealthCheckNotAvailable when container has no health check configured
- Only log first docker health check failure and skip logging for ErrDockerHealthCheckNotAvailable
- Use mon.Context() instead of mon.task.Context() to avoid nil panic
- Move health check implementations from monitor/ to new check/ package
- Add h2c, tcp4/6, udp4/6 scheme support to agent health check API
- Add timeout URL parameter to agent health check endpoint
- Remove unused agent dependencies (dnsproviders, lego, various cloud SDKs)
- Use net.JoinHostPort instead of fmt.Sprintf for port joining
Moved non-agent-specific logic from agent/pkg/agent/ to internal/agentpool/:
- pool.go: Agent pool management (Get, Add, Remove, List, Iter, etc.)
- http_requests.go: HTTP utilities (health checks, forwarding, websockets, reverse proxy)
- agent.go: Agent struct with HTTP client management
This separates general-purpose pool management from agent-specific configuration,
improving code organization and making the agent package focused on agent config only.
- Enhanced error handling in the UDP server to properly manage EOF and closed connection scenarios.
- Ensured that bytes read from the client are forwarded before handling errors.
- Added checks to avoid logging noise for expected shutdown conditions.
- Adjusted headerSize calculation to reflect the correct size based on field definitions.
- Changed HostLength and PortLength types from uint8 to byte.
- Updated PROTOCOL.md to reflect the new header size and structure.
- Updated error handling in the UDP server to ignore io.EOF errors when reading from client connections.
- Added a check to return early if no bytes are read from the client connection.
- Ensured proper closure of tcpListener in the main.go file during cancellation.
- Removed the streamServerAddr field from AgentConfig to streamline configuration.
- Updated StartWithCerts, NewTCPClient, and NewUDPClient methods to use Addr directly for establishing connections.
- Eliminated the getStreamServerAddr method as it is no longer needed.
- Introduced a new `Bind` field in the route configuration to specify the address to listen on for TCP and UDP routes.
- Defaulted the bind address to "0.0.0.0" if not provided.
- Enhanced validation to ensure the bind address is a valid IP.
- Updated stream initialization to use the correct network type (tcp4/tcp6 or udp4/udp6) based on the bind address.
- Refactored stream creation functions to accept the network type as a parameter.
- Use agent.NewAgent() for properly configured certificates matching real usage
- Migrate to testify/require for assertions
- Add tests for UDP server rejecting clients with invalid certificates
- Use t.Context() for lifecycle management
- Introduced a new method `GetCertInfos` to fetch details of all available certificates.
- Updated the `Info` handler to return an array of `CertInfo` instead of a single certificate.
- Improved error handling for cases with no available certificates.
- Refactored related error messages for clarity.
- Introduced `StreamPort` field in `NewAgentRequest` for agent configuration.
- Implemented default behavior for `StreamPort` to be `Port + 1` if not specified.
- Added validation to ensure `StreamPort` is within the valid range (1-65535).
- Add `StreamPort` configuration to agent configuration and environment variables
- Implement TCP and UDP stream client support in agent package
- Update agent verification to test stream connectivity (TCP/UDP)
- Add `/info` endpoint to agent HTTP handler for version, name, runtime, and stream port
- Remove /version, /name, /runtime APIs, replaced by /info
- Update agent compose template to expose stream port for TCP and UDP
- Update agent creation API to optionally specify stream port (defaults to port + 1)
- Modify `StreamRoute` to pass agent configuration to stream implementations
- Update `TCPTCPStream` and `UDPUDPStream` to use agent stream tunneling when agent is configured
- Add support for both direct connections and agent-tunneled connections in stream routes
This enables agents to handle TCP and UDP route tunneling, expanding the proxy capabilities beyond HTTP-only connections.
- Updated various files to utilize gperr.Group for cleaner concurrency error handling.
- Removed sync.WaitGroup usage, simplifying the code structure.
- Ensured consistent error reporting across different components.
Extra providers were not being properly initialized during NewProvider(),
causing certificate registration and renewal scheduling to be skipped.
- Add ConfigExtra type with idx field for provider indexing
- Add MergeExtraConfig() for inheriting main provider settings
- Add setupExtraProviders() for recursive extra provider initialization
- Refactor NewProvider to return error and call setupExtraProviders()
- Add provider-scoped logger with "main" or "extra[N]" name
- Add batch operations: ObtainCertIfNotExistsAll(), ObtainCertAll()
- Add ForceExpiryAll() with completion tracking via WaitRenewalDone()
- Add RenewMode (force/ifNeeded) for controlling renewal behavior
- Add PrintCertExpiriesAll() for logging all provider certificate expiries
Summary of staged changes:
- config.go: Added ConfigExtra type, MergeExtraConfig(), recursive validation with path uniqueness checking
- provider.go: Added provider indexing, scoped logger, batch cert operations, force renewal with completion tracking, RenewMode control
- setup.go: New file with setupExtraProviders() for proper extra provider initialization
- setup_test.go: New tests for extra provider setup
- multi_cert_test.go: New tests for multi-certificate functionality
- renew.go: Updated to use new provider API with error handling
- state.go: Updated to handle NewProvider error return
Multi-certificate, SNI matching with exact map and suffix tree
Add support for multiple TLS certificates with SNI-based selection. The
root provider maintains a single centralized SNI matcher that uses an
exact match map for O(1) lookups, falling back to a suffix tree for
wildcard matching.
Key features:
- Add `Extra []Config` field to autocert.Config for additional certificates
- Each extra entry must specify unique `cert_path` and `key_path`
- Extra certs inherit main config (except `email` and `extra` fields)
- Extra certs participate in ACME obtain/renew cycles independently
- SNI selection precedence: exact match > wildcard match, main > extra
- Single centralized SNI matcher on root provider rebuilt after cert changes
The SNI matcher structure:
- Exact match map: O(1) lookup for exact domain matches
- Suffix tree: Efficient wildcard matching (e.g., *.example.com)
Implementation details:
- Provider.GetCert() now uses SNI from ClientHelloInfo for selection
- Main cert is returned as fallback when no SNI match is found
- Extra providers are created as child providers with merged configs
- SNI matcher is rebuilt after Setup() and after ObtainCert() completes