Beispiel #1
0
func TestBackoff(t *testing.T) {
	b := net.Backoff{}

	eq := func(d time.Duration, ms int) {
		a := int(d / time.Millisecond)
		if a != ms {
			t.Errorf("Backoff #%d:  %v should be %v", b.CurrentTry, a, ms)
		}
	}

	eq(b.NextDelay(), 5000)
	eq(b.NextDelay(), 6870)
	eq(b.NextDelay(), 9440)
	eq(b.NextDelay(), 12972)
	eq(b.NextDelay(), 17826)
	eq(b.NextDelay(), 24494)
	eq(b.NextDelay(), 33658)
	eq(b.NextDelay(), 46250)
	eq(b.NextDelay(), 63553)
	eq(b.NextDelay(), 87329)
	eq(b.NextDelay(), 120000)
}
Beispiel #2
0
func (s *Server) logQueryLoop(logID int64, logURL string, start int64, entryChan chan<- entryBatch) {
	defer close(entryChan)

	numPerQuery := int64(10000)
	backoff := denet.Backoff{}
	client := ctclient.Client{
		LogURL: logURL,
	}

	var sth *ctclient.STH
	ticker := time.NewTicker(2 * time.Minute)
	defer ticker.Stop()
	oneTick := make(chan struct{}, 1)
	oneTick <- struct{}{}
	var err error

	for {
		if atomic.LoadInt32(&s.stopping) != 0 {
			break
		}

		if sth == nil {
			select {
			case <-ticker.C:
			case <-oneTick:
			case <-s.stopChan:
				continue
			}

			log.Debug("getting STH...")
			sth, err = client.GetSTH()
			if err != nil {
				log.Errore(err, "failed to get STH")
				backoff.Sleep()
				continue
			}
		}

		end := start + numPerQuery
		if end > sth.TreeSize {
			end = sth.TreeSize
		}
		if start >= end {
			log.Debugf("log %d: at the end", logID)
			sth = nil
			continue
		}

		log.Debugf("get entries: %#v: (%d,%d)", logURL, start, end-1)
		entries, numEntries, err := client.GetEntries(start, end-1)
		if err == nil {
			backoff.Reset()

			entryChan <- entryBatch{
				Entries:    entries,
				NumEntries: numEntries,
				StartIndex: start,
			}

			start += int64(numEntries)
			//err := s.processEntries(logID, entries, &start, numEntries)
			//log.Fatale(err, "update log height")
		} else {
			log.Errore(err, "cannot get entries for log: ", logURL)
			backoff.Sleep()
		}
	}

	log.Debugf("log reader stopped: %#v", logURL)
}
Beispiel #3
0
// Completes a given challenge, polling it until it is complete. Can be
// cancelled using ctx.
//
// dnsName is the hostname which is being authorized. webPaths and priorKeyFunc
// are passed to responders.
//
// The return value indicates whether the whole authorization has been invalidated
// (set to "failed" status) as a result of an error. In this case a new authorization
// must be created.
func CompleteChallenge(c *acmeapi.Client, ch *acmeapi.Challenge, dnsName string, ccfg responder.ChallengeConfig, ctx context.Context) (invalidated bool, err error) {
	log.Debugf("attempting challenge type %s", ch.Type)

	var certs [][]byte
	for _, c := range ch.Certs {
		certs = append(certs, c)
	}

	r, err := responder.New(responder.Config{
		Type:                   ch.Type,
		Token:                  ch.Token,
		AccountKey:             c.AccountKey,
		Hostname:               dnsName,
		AcceptableCertificates: certs,
		ChallengeConfig:        ccfg,
	})

	if err != nil {
		log.Debuge(err, "challenge instantiation failed")
		return false, err
	}

	err = r.Start()
	if err != nil {
		log.Debuge(err, "challenge start failed")
		return false, err
	}

	defer r.Stop()

	err = c.RespondToChallenge(ch, r.Validation(), r.ValidationSigningKey(), ctx)
	if err != nil {
		return false /* ??? */, err
	}

	b := denet.Backoff{
		InitialDelay: 5 * time.Second,
		MaxDelay:     30 * time.Second,
	}

	for {
		log.Debug("waiting to poll challenge")
		select {
		case <-ctx.Done():
			return true, ctx.Err()
		case <-r.RequestDetectedChan():
			log.Debug("request detected")
		case <-time.After(b.NextDelay()):
		}

		log.Debug("querying challenge status")
		err := c.WaitLoadChallenge(ch, ctx)
		if err != nil {
			return false, err
		}

		if ch.Status.Final() {
			log.Debug("challenge now in final state")
			break
		}
	}

	if ch.Status != "valid" {
		return true, fmt.Errorf("challenge failed with status %#v", ch.Status)
	}

	return false, nil
}