From db83afcb09d11ac7ade82b5769b9ef3c24af9ff2 Mon Sep 17 00:00:00 2001 From: Rico Date: Sun, 13 Sep 2026 20:07:21 +0200 Subject: [PATCH 1/5] fix: ensure clients can only be registered once Removes a left-over RegisterClient() call and adds a check within the RegisterClient() method to prevent duplicated registrations. fixes #116 --- internal/broadcast/dispatcher.go | 11 +++++++++-- internal/broadcast/dispatcher_test.go | 12 ++++++++++++ internal/certstream/certstream.go | 2 -- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/internal/broadcast/dispatcher.go b/internal/broadcast/dispatcher.go index df8d1a7..56a3ad8 100644 --- a/internal/broadcast/dispatcher.go +++ b/internal/broadcast/dispatcher.go @@ -33,12 +33,19 @@ func NewDispatcher() *Dispatcher { // RegisterClient adds a client to the list of clients of the Dispatcher. // The client will receive certificate broadcasts right after registration. func (bm *Dispatcher) RegisterClient(c CertProcessor) { - // TODO: check if the client is already registered bm.clientLock.Lock() + defer bm.clientLock.Unlock() + + for _, client := range bm.clients { + if client == c { + log.Printf("Client already registered: %s\n", c.Name()) + return + } + } + bm.clients = append(bm.clients, c) log.Printf("Added new client. Clients: %d, Capacity: %d\n", len(bm.clients), cap(bm.clients)) metrics.Prometheus.RegisterClient(c.Name(), func() float64 { return float64(c.SkippedCerts()) }) - bm.clientLock.Unlock() } // UnregisterClient removes a client from the list of clients of the Dispatcher. diff --git a/internal/broadcast/dispatcher_test.go b/internal/broadcast/dispatcher_test.go index 17bf2f6..c6b2e9d 100644 --- a/internal/broadcast/dispatcher_test.go +++ b/internal/broadcast/dispatcher_test.go @@ -14,6 +14,18 @@ func newDispatcherTestWebsocketClient(name string) *WebsocketClient { } } +func TestDispatcherRegisterClientTwice(t *testing.T) { + d := &Dispatcher{} + client := newDispatcherTestWebsocketClient("client-1") + + d.RegisterClient(client) + d.RegisterClient(client) + + if got := len(d.clients); got != 1 { + t.Fatalf("expected 1 registered client after duplicate register, got %d", got) + } +} + func TestDispatcherUnregisterWebsocketClient(t *testing.T) { d := &Dispatcher{} client := newDispatcherTestWebsocketClient("client-1") diff --git a/internal/certstream/certstream.go b/internal/certstream/certstream.go index fef83a2..481a7d8 100644 --- a/internal/certstream/certstream.go +++ b/internal/certstream/certstream.go @@ -96,8 +96,6 @@ func NewCertstreamServer(cfg config.Config) (*Certstream, error) { string(streamProcessor.Compression), cfg.General.BufferSizes.Websocket, ) - - broadcast.ClientHandler.RegisterClient(c) default: log.Printf("Unknown stream processor type '%s' for %s. Skipping...\n", streamProcessor.Type, streamProcessor.Name) } From 629054340d9574c6bf062a7a0444132cdc9f0498 Mon Sep 17 00:00:00 2001 From: Rico Date: Sun, 13 Sep 2026 20:08:15 +0200 Subject: [PATCH 2/5] chore: bump version to 1.10.1 --- internal/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/config/config.go b/internal/config/config.go index ae59ee8..72e09f0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,7 +13,7 @@ import ( var ( // AppConfig holds the parsed configuration. AppConfig Config - Version = "1.10.0" + Version = "1.10.1" ErrInvalidConfig = errors.New("invalid configuration") URLPathRegex = regexp.MustCompile(`^(/[a-zA-Z0-9\-._]+)+$`) From 7ab7003d0c1d0a3233c6958d16d854402ac09dc5 Mon Sep 17 00:00:00 2001 From: Rico Date: Sun, 13 Sep 2026 20:08:37 +0200 Subject: [PATCH 3/5] docs(changelog): add missing changelog entries for 1.10.0 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c153231..21cd3b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,16 +30,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated http client settings to prevent timeouts and other connectivity issues - Updated http server settings to allow for higher delays - Updated batch size from 100 to 256 (#97) +- Use config.yaml as default value for --config arg (6aed28e) ### Fixed - Prevent excessive tile fetching for static CT logs (#104) - Fix off-by-one is Static CT path causing refetches of non-growing logs by @FiloSottile in https://github.com/d-Rickyy-b/certstream-server-go/pull/114 -- Calculate correct starting tile index for static ct logs (a2b4a9f) - Use proper websocket close code (1008) instead of 1005, which wasn't sent to the client (76ff240) +- Properly handle websocket client disconnections (750ed24) - Respect ct_index path in config file for the `create-index` command (67838a9) - Ensure all additionalLog entries are processed correctly (c8bd735) - Reload CT index from metrics before restarting the worker (85e90bf, #113) +- Use double dashes for docker entrypoint --config argument (#101) +- Use ct_index path from config file if no outfile is given (#102) +- Close temp file before renaming it (fb10013) ## [1.9.0] - 2026-04-03 From daa9cedf0a74eeb149a80f28d875da8f0a8019ea Mon Sep 17 00:00:00 2001 From: Rico Date: Sun, 13 Sep 2026 23:24:09 +0200 Subject: [PATCH 4/5] docs(changelog): add fixes for 1.10.1 --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21cd3b4..231c762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +## [1.10.1] - 2026-09-13 + +### Fixed + +- Prevent duplicate client registration by checking if the client is already registered before adding it (#116) + ## [1.10.0] - 2026-09-13 ### Added @@ -255,7 +261,8 @@ Fixed the connection issue due to the offline Google loglist urls. Initial release! First stable version of certstream-server-go is published as v1.0.0 -[unreleased]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.10.0...HEAD +[unreleased]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.10.1...HEAD +[1.10.1]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.10.0...v1.10.1 [1.10.0]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.9.0...v1.10.0 [1.9.0]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.8.2...v1.9.0 [1.8.2]: https://github.com/d-Rickyy-b/certstream-server-go/compare/v1.8.1...v1.8.2 From c248d969d722f0a6ca39b8a9aad24d0344ffaddc Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 14 Sep 2026 00:31:02 +0200 Subject: [PATCH 5/5] build: update release action to push docker dev images --- .github/workflows/release_build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release_build.yml b/.github/workflows/release_build.yml index d11b918..c5d15f3 100644 --- a/.github/workflows/release_build.yml +++ b/.github/workflows/release_build.yml @@ -55,11 +55,13 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Run GoReleaser (dev snapshot) + - name: Run GoReleaser (dev) if: github.ref == 'refs/heads/dev' uses: goreleaser/goreleaser-action@v7 with: version: latest - args: release --snapshot --clean --config .github/goreleaser.yml + args: release --clean --config .github/goreleaser.yml --skip=validate env: + GORELEASER_CURRENT_TAG: dev + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}