mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-12 00:19:08 +02:00
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package certproof
|
|
|
|
import (
|
|
"context"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/netbirdio/netbird/shared/management/certposture"
|
|
"github.com/netbirdio/netbird/shared/management/proto"
|
|
)
|
|
|
|
const collectTimeout = 10 * time.Second
|
|
|
|
// Collector runs CollectProofs with a deadline and at most one collection at a time.
|
|
// Token, TPM and keychain calls cannot be interrupted, so a collection that overruns is
|
|
// abandoned rather than awaited, and a new one is refused until it has finished. The
|
|
// zero value is ready to use.
|
|
type Collector struct {
|
|
busy atomic.Bool
|
|
// timeout overrides collectTimeout when set.
|
|
timeout time.Duration
|
|
}
|
|
|
|
// Collect answers the certificate challenges in checks, returning no proofs when there
|
|
// are no challenges, when a previous collection is still running, or when this one does
|
|
// not finish in time. Missing proofs fail the certificate check on management.
|
|
func (c *Collector) Collect(ctx context.Context, checks []*proto.Checks, peerKey []byte, cfg Config) []certposture.Proof {
|
|
return c.collect(ctx, checks, func(ctx context.Context) []certposture.Proof {
|
|
return CollectProofs(ctx, checks, peerKey, cfg)
|
|
})
|
|
}
|
|
|
|
func (c *Collector) collect(ctx context.Context, checks []*proto.Checks, run func(context.Context) []certposture.Proof) []certposture.Proof {
|
|
if len(certificateChallenges(checks)) == 0 {
|
|
return nil
|
|
}
|
|
if !c.busy.CompareAndSwap(false, true) {
|
|
log.Warnf("certificate posture: previous proof collection is still running, sending no proofs")
|
|
return nil
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, c.deadline())
|
|
defer cancel()
|
|
|
|
done := make(chan []certposture.Proof, 1)
|
|
go func() {
|
|
defer c.busy.Store(false)
|
|
done <- run(ctx)
|
|
}()
|
|
|
|
select {
|
|
case proofs := <-done:
|
|
return proofs
|
|
case <-ctx.Done():
|
|
log.Warnf("certificate posture: proof collection did not finish within %s, sending no proofs", c.deadline())
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (c *Collector) deadline() time.Duration {
|
|
if c.timeout > 0 {
|
|
return c.timeout
|
|
}
|
|
return collectTimeout
|
|
}
|