Improve signer robustness
- let client simulator send some garbage bytes before starting real commands - handle EOF during reads
This commit is contained in:
parent
e5dcf7afa9
commit
9905d748d9
2 changed files with 72 additions and 32 deletions
|
@ -21,7 +21,9 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -155,16 +157,27 @@ func (g *TestCommandGenerator) HandleResponse(frame []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
||||||
const (
|
|
||||||
healthInterval = 5 * time.Second
|
|
||||||
startPause = 3 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
announce *messages.CommandAnnounce
|
announce *messages.CommandAnnounce
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// write some leading garbage to test signer robustness
|
||||||
|
_, _ = io.CopyN(os.Stdout, rand.Reader, 50) //nolint:gomnd
|
||||||
|
|
||||||
|
announce, err = messages.BuildCommandAnnounce(messages.CmdHealth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("build command announce failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.commands <- &protocol.Command{Announce: announce, Command: &messages.HealthCommand{}}
|
||||||
|
|
||||||
|
const (
|
||||||
|
healthInterval = 5 * time.Second
|
||||||
|
crlInterval = 15 * time.Minute
|
||||||
|
startPause = 3 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
g.logger.Info("start generating commands")
|
g.logger.Info("start generating commands")
|
||||||
|
|
||||||
time.Sleep(startPause)
|
time.Sleep(startPause)
|
||||||
|
@ -179,17 +192,18 @@ func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
||||||
Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"},
|
Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"},
|
||||||
}
|
}
|
||||||
|
|
||||||
timer := time.NewTimer(healthInterval)
|
healthTimer := time.NewTimer(healthInterval)
|
||||||
|
crlTimer := time.NewTimer(crlInterval)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
_ = timer.Stop()
|
_ = healthTimer.Stop()
|
||||||
|
|
||||||
g.logger.Info("stopping health check loop")
|
g.logger.Info("stopping health check loop")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
case <-timer.C:
|
case <-healthTimer.C:
|
||||||
announce, err = messages.BuildCommandAnnounce(messages.CmdHealth)
|
announce, err = messages.BuildCommandAnnounce(messages.CmdHealth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("build command announce failed: %w", err)
|
return fmt.Errorf("build command announce failed: %w", err)
|
||||||
|
@ -199,9 +213,14 @@ func (g *TestCommandGenerator) GenerateCommands(ctx context.Context) error {
|
||||||
Announce: announce,
|
Announce: announce,
|
||||||
Command: &messages.HealthCommand{},
|
Command: &messages.HealthCommand{},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
timer.Reset(healthInterval)
|
healthTimer.Reset(healthInterval)
|
||||||
|
case <-crlTimer.C:
|
||||||
|
g.commands <- &protocol.Command{
|
||||||
|
Announce: announce,
|
||||||
|
Command: &messages.FetchCRLCommand{IssuerID: "sub-ecc_person_2022"},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,44 +268,61 @@ func (c *clientSimulator) writeCommand() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const responseAnnounceTimeout = 30 * time.Second
|
||||||
|
const responseDataTimeout = 2 * time.Second
|
||||||
|
|
||||||
func (c *clientSimulator) handleResponseAnnounce() error {
|
func (c *clientSimulator) handleResponseAnnounce() error {
|
||||||
c.logger.Trace("waiting for response announce")
|
c.logger.Trace("waiting for response announce")
|
||||||
|
|
||||||
frame := <-c.framesIn
|
select {
|
||||||
|
case frame := <-c.framesIn:
|
||||||
|
if frame == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.commandGenerator.HandleResponseAnnounce(frame); err != nil {
|
||||||
|
return fmt.Errorf("response announce handling failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.nextState(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-time.After(responseAnnounceTimeout):
|
||||||
|
c.logger.Warn("response announce timeout expired")
|
||||||
|
|
||||||
|
c.protocolState = cmdAnnounce
|
||||||
|
|
||||||
if frame == nil {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.commandGenerator.HandleResponseAnnounce(frame); err != nil {
|
|
||||||
return fmt.Errorf("response announce handling failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.nextState(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientSimulator) handleResponseData() error {
|
func (c *clientSimulator) handleResponseData() error {
|
||||||
c.logger.Trace("waiting for response data")
|
c.logger.Trace("waiting for response data")
|
||||||
|
|
||||||
frame := <-c.framesIn
|
select {
|
||||||
|
case frame := <-c.framesIn:
|
||||||
|
if frame == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.commandGenerator.HandleResponse(frame); err != nil {
|
||||||
|
return fmt.Errorf("response handler failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.nextState(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
case <-time.After(responseDataTimeout):
|
||||||
|
c.logger.Warn("response data timeout expired")
|
||||||
|
|
||||||
|
c.protocolState = cmdAnnounce
|
||||||
|
|
||||||
if frame == nil {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.commandGenerator.HandleResponse(frame); err != nil {
|
|
||||||
return fmt.Errorf("response handler failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.nextState(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientSimulator) Run(ctx context.Context) error {
|
func (c *clientSimulator) Run(ctx context.Context) error {
|
||||||
|
|
|
@ -146,6 +146,10 @@ func (c *COBSFramer) readRaw(reader io.Reader) ([]byte, error) {
|
||||||
|
|
||||||
count, err := reader.Read(buf)
|
count, err := reader.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("could not read data: %w", err)
|
return nil, fmt.Errorf("could not read data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue