@@ -102,6 +102,9 @@ func newFQDNSetBucketKey(name Name, orderNames []string) (string, error) { //nol
102102// - allow-only: when neither check nor spend are true, the transaction will
103103// be considered "allowed" regardless of the bucket's capacity. This is
104104// useful for limits that are disabled.
105+ //
106+ // The zero value of Transaction is an allow-only transaction and is valid even if
107+ // it would fail validateTransaction (for instance because cost and burst are zero).
105108type Transaction struct {
106109 bucketKey string
107110 limit limit
@@ -126,6 +129,14 @@ func validateTransaction(txn Transaction) (Transaction, error) {
126129 if txn .cost < 0 {
127130 return Transaction {}, ErrInvalidCost
128131 }
132+ if txn .limit .Burst == 0 {
133+ // This should never happen. If the limit was loaded from a file,
134+ // Burst was validated then. If this is a zero-valued Transaction
135+ // (that is, an allow-only transaction), then validateTransaction
136+ // shouldn't be called because zero-valued transactions are automatically
137+ // valid.
138+ return Transaction {}, fmt .Errorf ("invalid limit, burst must be > 0" )
139+ }
129140 if txn .cost > txn .limit .Burst {
130141 return Transaction {}, ErrInvalidCostOverLimit
131142 }
@@ -160,9 +171,9 @@ func newSpendOnlyTransaction(limit limit, bucketKey string, cost int64) (Transac
160171 })
161172}
162173
163- func newAllowOnlyTransaction () ( Transaction , error ) {
174+ func newAllowOnlyTransaction () Transaction {
164175 // Zero values are sufficient.
165- return validateTransaction ( Transaction {})
176+ return Transaction {}
166177}
167178
168179// TransactionBuilder is used to build Transactions for various rate limits.
@@ -194,7 +205,7 @@ func (builder *TransactionBuilder) registrationsPerIPAddressTransaction(ip net.I
194205 limit , err := builder .getLimit (NewRegistrationsPerIPAddress , bucketKey )
195206 if err != nil {
196207 if errors .Is (err , errLimitDisabled ) {
197- return newAllowOnlyTransaction ()
208+ return newAllowOnlyTransaction (), nil
198209 }
199210 return Transaction {}, err
200211 }
@@ -212,7 +223,7 @@ func (builder *TransactionBuilder) registrationsPerIPv6RangeTransaction(ip net.I
212223 limit , err := builder .getLimit (NewRegistrationsPerIPv6Range , bucketKey )
213224 if err != nil {
214225 if errors .Is (err , errLimitDisabled ) {
215- return newAllowOnlyTransaction ()
226+ return newAllowOnlyTransaction (), nil
216227 }
217228 return Transaction {}, err
218229 }
@@ -229,7 +240,7 @@ func (builder *TransactionBuilder) ordersPerAccountTransaction(regId int64) (Tra
229240 limit , err := builder .getLimit (NewOrdersPerAccount , bucketKey )
230241 if err != nil {
231242 if errors .Is (err , errLimitDisabled ) {
232- return newAllowOnlyTransaction ()
243+ return newAllowOnlyTransaction (), nil
233244 }
234245 return Transaction {}, err
235246 }
@@ -250,7 +261,10 @@ func (builder *TransactionBuilder) FailedAuthorizationsPerDomainPerAccountCheckO
250261 return nil , err
251262 }
252263 limit , err := builder .getLimit (FailedAuthorizationsPerDomainPerAccount , perAccountBucketKey )
253- if err != nil && ! errors .Is (err , errLimitDisabled ) {
264+ if err != nil {
265+ if errors .Is (err , errLimitDisabled ) {
266+ return []Transaction {newAllowOnlyTransaction ()}, nil
267+ }
254268 return nil , err
255269 }
256270
@@ -287,7 +301,10 @@ func (builder *TransactionBuilder) FailedAuthorizationsPerDomainPerAccountSpendO
287301 return Transaction {}, err
288302 }
289303 limit , err := builder .getLimit (FailedAuthorizationsPerDomainPerAccount , perAccountBucketKey )
290- if err != nil && ! errors .Is (err , errLimitDisabled ) {
304+ if err != nil {
305+ if errors .Is (err , errLimitDisabled ) {
306+ return newAllowOnlyTransaction (), nil
307+ }
291308 return Transaction {}, err
292309 }
293310
@@ -317,7 +334,10 @@ func (builder *TransactionBuilder) FailedAuthorizationsForPausingPerDomainPerAcc
317334 return Transaction {}, err
318335 }
319336 limit , err := builder .getLimit (FailedAuthorizationsForPausingPerDomainPerAccount , perAccountBucketKey )
320- if err != nil && ! errors .Is (err , errLimitDisabled ) {
337+ if err != nil {
338+ if errors .Is (err , errLimitDisabled ) {
339+ return newAllowOnlyTransaction (), nil
340+ }
321341 return Transaction {}, err
322342 }
323343
@@ -351,9 +371,18 @@ func (builder *TransactionBuilder) certificatesPerDomainCheckOnlyTransactions(re
351371 if err != nil {
352372 return nil , err
353373 }
374+ accountOverride := true
354375 perAccountLimit , err := builder .getLimit (CertificatesPerDomainPerAccount , perAccountLimitBucketKey )
355- if err != nil && ! errors .Is (err , errLimitDisabled ) {
356- return nil , err
376+ if err != nil {
377+ // The CertificatesPerDomainPerAccount limit never has a default. If there is an override for it,
378+ // the above call will return the override. But if there is none, it will return errLimitDisabled.
379+ // In that case we want to continue, but make sure we don't reference `perAccountLimit` because it
380+ // is not a valid limit.
381+ if errors .Is (err , errLimitDisabled ) {
382+ accountOverride = false
383+ } else {
384+ return nil , err
385+ }
357386 }
358387
359388 var txns []Transaction
@@ -362,9 +391,10 @@ func (builder *TransactionBuilder) certificatesPerDomainCheckOnlyTransactions(re
362391 if err != nil {
363392 return nil , err
364393 }
365- if perAccountLimit .isOverride () {
366- // An override is configured for the CertificatesPerDomainPerAccount
367- // limit.
394+ if accountOverride {
395+ if ! perAccountLimit .isOverride () {
396+ return nil , fmt .Errorf ("shouldn't happen: CertificatesPerDomainPerAccount limit is not an override" )
397+ }
368398 perAccountPerDomainKey , err := NewRegIdDomainBucketKey (CertificatesPerDomainPerAccount , regId , name )
369399 if err != nil {
370400 return nil , err
@@ -373,18 +403,20 @@ func (builder *TransactionBuilder) certificatesPerDomainCheckOnlyTransactions(re
373403 // bucket.
374404 txn , err := newCheckOnlyTransaction (perAccountLimit , perAccountPerDomainKey , 1 )
375405 if err != nil {
406+ if errors .Is (err , errLimitDisabled ) {
407+ continue
408+ }
376409 return nil , err
377410 }
378411 txns = append (txns , txn )
379412 } else {
380413 // Use the per domain bucket key when no per account per domain override
381414 // is configured.
382415 perDomainLimit , err := builder .getLimit (CertificatesPerDomain , perDomainBucketKey )
383- if errors .Is (err , errLimitDisabled ) {
384- // Skip disabled limit.
385- continue
386- }
387416 if err != nil {
417+ if errors .Is (err , errLimitDisabled ) {
418+ continue
419+ }
388420 return nil , err
389421 }
390422 // Add a check-only transaction for each per domain bucket.
@@ -417,9 +449,18 @@ func (builder *TransactionBuilder) CertificatesPerDomainSpendOnlyTransactions(re
417449 if err != nil {
418450 return nil , err
419451 }
452+ accountOverride := true
420453 perAccountLimit , err := builder .getLimit (CertificatesPerDomainPerAccount , perAccountLimitBucketKey )
421- if err != nil && ! errors .Is (err , errLimitDisabled ) {
422- return nil , err
454+ if err != nil {
455+ // The CertificatesPerDomainPerAccount limit never has a default. If there is an override for it,
456+ // the above call will return the override. But if there is none, it will return errLimitDisabled.
457+ // In that case we want to continue, but make sure we don't reference `perAccountLimit` because it
458+ // is not a valid limit.
459+ if errors .Is (err , errLimitDisabled ) {
460+ accountOverride = false
461+ } else {
462+ return nil , err
463+ }
423464 }
424465
425466 var txns []Transaction
@@ -428,9 +469,10 @@ func (builder *TransactionBuilder) CertificatesPerDomainSpendOnlyTransactions(re
428469 if err != nil {
429470 return nil , err
430471 }
431- if perAccountLimit .isOverride () {
432- // An override is configured for the CertificatesPerDomainPerAccount
433- // limit.
472+ if accountOverride {
473+ if ! perAccountLimit .isOverride () {
474+ return nil , fmt .Errorf ("shouldn't happen: CertificatesPerDomainPerAccount limit is not an override" )
475+ }
434476 perAccountPerDomainKey , err := NewRegIdDomainBucketKey (CertificatesPerDomainPerAccount , regId , name )
435477 if err != nil {
436478 return nil , err
@@ -444,11 +486,10 @@ func (builder *TransactionBuilder) CertificatesPerDomainSpendOnlyTransactions(re
444486 txns = append (txns , txn )
445487
446488 perDomainLimit , err := builder .getLimit (CertificatesPerDomain , perDomainBucketKey )
447- if errors .Is (err , errLimitDisabled ) {
448- // Skip disabled limit.
449- continue
450- }
451489 if err != nil {
490+ if errors .Is (err , errLimitDisabled ) {
491+ continue
492+ }
452493 return nil , err
453494 }
454495
@@ -462,11 +503,10 @@ func (builder *TransactionBuilder) CertificatesPerDomainSpendOnlyTransactions(re
462503 // Use the per domain bucket key when no per account per domain
463504 // override is configured.
464505 perDomainLimit , err := builder .getLimit (CertificatesPerDomain , perDomainBucketKey )
465- if errors .Is (err , errLimitDisabled ) {
466- // Skip disabled limit.
467- continue
468- }
469506 if err != nil {
507+ if errors .Is (err , errLimitDisabled ) {
508+ continue
509+ }
470510 return nil , err
471511 }
472512 // Add a spend-only transaction for each per domain bucket.
@@ -491,7 +531,7 @@ func (builder *TransactionBuilder) certificatesPerFQDNSetCheckOnlyTransaction(or
491531 limit , err := builder .getLimit (CertificatesPerFQDNSet , bucketKey )
492532 if err != nil {
493533 if errors .Is (err , errLimitDisabled ) {
494- return newAllowOnlyTransaction ()
534+ return newAllowOnlyTransaction (), nil
495535 }
496536 return Transaction {}, err
497537 }
@@ -509,7 +549,7 @@ func (builder *TransactionBuilder) CertificatesPerFQDNSetSpendOnlyTransaction(or
509549 limit , err := builder .getLimit (CertificatesPerFQDNSet , bucketKey )
510550 if err != nil {
511551 if errors .Is (err , errLimitDisabled ) {
512- return newAllowOnlyTransaction ()
552+ return newAllowOnlyTransaction (), nil
513553 }
514554 return Transaction {}, err
515555 }
0 commit comments