mirror of
https://github.com/caddyserver/caddy.git
synced 2025-03-06 21:19:03 -05:00
WIP: publication history
This commit is contained in:
parent
b987a60f89
commit
57958969c7
@ -17,7 +17,6 @@ import (
|
||||
"github.com/cloudflare/circl/hpke"
|
||||
"github.com/cloudflare/circl/kem"
|
||||
"github.com/libdns/libdns"
|
||||
"github.com/zeebo/blake3"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
|
||||
@ -382,9 +381,12 @@ func (dnsPub ECHDNSPublisher) Provision(ctx caddy.Context) error {
|
||||
}
|
||||
|
||||
func (dnsPub ECHDNSPublisher) PublisherKey() string {
|
||||
h := blake3.New()
|
||||
fmt.Fprintf(h, "%v", dnsPub.provider)
|
||||
return dnsPub.provider.(caddy.Module).CaddyModule().ID.Name() + ":" + string(h.Sum(nil))
|
||||
// TODO: Figure out what the key should be
|
||||
// h := blake3.New()
|
||||
// fmt.Fprintf(h, "%v", dnsPub.provider)
|
||||
// return fmt.Sprintf("%s::%s", dnsPub.provider.(caddy.Module).CaddyModule().ID, h.Sum(nil))
|
||||
return string(dnsPub.provider.(caddy.Module).CaddyModule().ID)
|
||||
|
||||
}
|
||||
|
||||
func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNames []string, configListBin []byte) error {
|
||||
@ -850,14 +852,34 @@ type ECHPublisher interface {
|
||||
|
||||
// Publishes the ECH config list for the given innerNames. Some publishers
|
||||
// may not need a list of inner/protected names, and can ignore the argument;
|
||||
// most, however, will want to use it as guidance to ensure the inner names
|
||||
// are associated with the proper ECH configs.
|
||||
// most, however, will want to use it to know which inner names are to be
|
||||
// associated with the given ECH config list.
|
||||
PublishECHConfigList(ctx context.Context, innerNames []string, echConfigList []byte) error
|
||||
}
|
||||
|
||||
type echConfigMeta struct {
|
||||
Created time.Time `json:"created"`
|
||||
Publications map[string]time.Time `json:"publications"` // map of publisher ID to timestamp of publication
|
||||
Created time.Time `json:"created"`
|
||||
Publications publicationHistory `json:"publications"`
|
||||
}
|
||||
|
||||
// publicationHistory is a map of publisher key to
|
||||
// map of inner name to timestamp
|
||||
type publicationHistory map[string]map[string]time.Time
|
||||
|
||||
func (hist publicationHistory) unpublishedNames(publisherKey string, serverNamesSet map[string]struct{}) map[string]struct{} {
|
||||
innerNamesSet, ok := hist[publisherKey]
|
||||
if !ok {
|
||||
// no history of this publisher publishing this config at all, so publish for entire set of names
|
||||
return serverNamesSet
|
||||
}
|
||||
for innerName := range innerNamesSet {
|
||||
// names in this loop have already had this config published by this publisher,
|
||||
// so delete them from the set of names to publish for
|
||||
//
|
||||
// TODO: Potentially utilize the timestamp (map value) to preserve server name for re-publication if enough time has passed
|
||||
delete(serverNamesSet, innerName)
|
||||
}
|
||||
return serverNamesSet
|
||||
}
|
||||
|
||||
// The key prefix when putting ECH configs in storage. After this
|
||||
|
@ -22,7 +22,9 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -430,25 +432,61 @@ func (t *TLS) Start() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshaling ECH config list: %v", err)
|
||||
}
|
||||
var serverNames []string
|
||||
|
||||
// by default, publish for all (non-outer) server names, unless
|
||||
// a specific list of names is configured
|
||||
var serverNamesSet map[string]struct{}
|
||||
if publication.DNSNames == nil {
|
||||
serverNamesSet = make(map[string]struct{}, len(t.serverNames))
|
||||
for name := range t.serverNames {
|
||||
serverNamesSet[name] = struct{}{}
|
||||
}
|
||||
} else {
|
||||
serverNamesSet = make(map[string]struct{}, len(publication.DNSNames))
|
||||
for _, name := range publication.DNSNames {
|
||||
serverNamesSet[name] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, publisher := range publication.publishers {
|
||||
dnsNames := publication.DNSNames
|
||||
if dnsNames == nil {
|
||||
// by default, publish for all (non-outer) server names; convert
|
||||
// de-duplicated map of server names to a slice
|
||||
if serverNames == nil {
|
||||
serverNames = make([]string, 0, len(t.serverNames))
|
||||
for sn := range t.serverNames {
|
||||
serverNames = append(serverNames, sn)
|
||||
publisherKey := publisher.PublisherKey()
|
||||
for _, cfg := range echCfgList {
|
||||
serverNamesSet = cfg.meta.Publications.unpublishedNames(publisherKey, serverNamesSet)
|
||||
}
|
||||
if len(serverNamesSet) > 0 {
|
||||
dnsNamesToPublish := make([]string, 0, len(serverNamesSet))
|
||||
for name := range serverNamesSet {
|
||||
dnsNamesToPublish = append(dnsNamesToPublish, name)
|
||||
}
|
||||
pubTime := time.Now()
|
||||
err := publisher.PublishECHConfigList(t.ctx, dnsNamesToPublish, echCfgListBin)
|
||||
if err != nil {
|
||||
t.logger.Error("publishing ECH configuration list",
|
||||
zap.Strings("for_dns_names", publication.DNSNames),
|
||||
zap.Error(err))
|
||||
}
|
||||
|
||||
// update publication history
|
||||
for _, cfg := range echCfgList {
|
||||
if cfg.meta.Publications == nil {
|
||||
cfg.meta.Publications = make(publicationHistory)
|
||||
}
|
||||
if _, ok := cfg.meta.Publications[publisherKey]; !ok {
|
||||
cfg.meta.Publications[publisherKey] = make(map[string]time.Time)
|
||||
}
|
||||
for _, name := range dnsNamesToPublish {
|
||||
cfg.meta.Publications[publisherKey][name] = pubTime
|
||||
}
|
||||
metaBytes, err := json.Marshal(cfg.meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshaling ECH config metadata: %v", err)
|
||||
}
|
||||
parentKey := path.Join(echConfigsKey, strconv.Itoa(int(cfg.ConfigID)))
|
||||
metaKey := path.Join(parentKey, "meta.json")
|
||||
if err := t.ctx.Storage().Store(t.ctx, metaKey, metaBytes); err != nil {
|
||||
return fmt.Errorf("storing ECH config metadata: %v", err)
|
||||
}
|
||||
}
|
||||
dnsNames = serverNames
|
||||
}
|
||||
err := publisher.PublishECHConfigList(t.ctx, dnsNames, echCfgListBin)
|
||||
if err != nil {
|
||||
t.logger.Error("publishing ECH configuration list",
|
||||
zap.Strings("for_dns_names", publication.DNSNames),
|
||||
zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user