[fuzz] only one way to set config variables
This commit is contained in:
parent
7dcc3dbcd1
commit
5965578c56
221
fuzz.go
221
fuzz.go
|
@ -1,7 +1,6 @@
|
||||||
package p2p
|
package p2p
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -15,58 +14,6 @@ const (
|
||||||
FuzzModeDelay
|
FuzzModeDelay
|
||||||
)
|
)
|
||||||
|
|
||||||
type FuzzConnConfig struct {
|
|
||||||
Mode int
|
|
||||||
MaxDelay time.Duration
|
|
||||||
ProbDropRW float64
|
|
||||||
ProbDropConn float64
|
|
||||||
ProbSleep float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultFuzzConnConfig() *FuzzConnConfig {
|
|
||||||
return &FuzzConnConfig{
|
|
||||||
Mode: FuzzModeDrop,
|
|
||||||
MaxDelay: 3 * time.Second,
|
|
||||||
ProbDropRW: 0.2,
|
|
||||||
ProbDropConn: 0.00,
|
|
||||||
ProbSleep: 0.00,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func FuzzConn(conn net.Conn) net.Conn {
|
|
||||||
return FuzzConnFromConfig(conn, defaultFuzzConnConfig())
|
|
||||||
}
|
|
||||||
|
|
||||||
func FuzzConnFromConfig(conn net.Conn, config *FuzzConnConfig) net.Conn {
|
|
||||||
return &FuzzedConnection{
|
|
||||||
conn: conn,
|
|
||||||
start: make(<-chan time.Time),
|
|
||||||
active: true,
|
|
||||||
mode: config.Mode,
|
|
||||||
maxDelay: config.MaxDelay,
|
|
||||||
probDropRW: config.ProbDropRW,
|
|
||||||
probDropConn: config.ProbDropConn,
|
|
||||||
probSleep: config.ProbSleep,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func FuzzConnAfter(conn net.Conn, d time.Duration) net.Conn {
|
|
||||||
return FuzzConnAfterFromConfig(conn, d, defaultFuzzConnConfig())
|
|
||||||
}
|
|
||||||
|
|
||||||
func FuzzConnAfterFromConfig(conn net.Conn, d time.Duration, config *FuzzConnConfig) net.Conn {
|
|
||||||
return &FuzzedConnection{
|
|
||||||
conn: conn,
|
|
||||||
start: time.After(d),
|
|
||||||
active: false,
|
|
||||||
mode: config.Mode,
|
|
||||||
maxDelay: config.MaxDelay,
|
|
||||||
probDropRW: config.ProbDropRW,
|
|
||||||
probDropConn: config.ProbDropConn,
|
|
||||||
probSleep: config.ProbSleep,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FuzzedConnection wraps any net.Conn and depending on the mode either delays
|
// FuzzedConnection wraps any net.Conn and depending on the mode either delays
|
||||||
// reads/writes or randomly drops reads/writes/connections.
|
// reads/writes or randomly drops reads/writes/connections.
|
||||||
type FuzzedConnection struct {
|
type FuzzedConnection struct {
|
||||||
|
@ -76,45 +23,110 @@ type FuzzedConnection struct {
|
||||||
start <-chan time.Time
|
start <-chan time.Time
|
||||||
active bool
|
active bool
|
||||||
|
|
||||||
mode int
|
config *FuzzConnConfig
|
||||||
maxDelay time.Duration
|
}
|
||||||
probDropRW float64
|
|
||||||
probDropConn float64
|
// FuzzConnConfig is a FuzzedConnection configuration.
|
||||||
probSleep float64
|
type FuzzConnConfig struct {
|
||||||
|
Mode int
|
||||||
|
MaxDelay time.Duration
|
||||||
|
ProbDropRW float64
|
||||||
|
ProbDropConn float64
|
||||||
|
ProbSleep float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultFuzzConnConfig returns the default config.
|
||||||
|
func DefaultFuzzConnConfig() *FuzzConnConfig {
|
||||||
|
return &FuzzConnConfig{
|
||||||
|
Mode: FuzzModeDrop,
|
||||||
|
MaxDelay: 3 * time.Second,
|
||||||
|
ProbDropRW: 0.2,
|
||||||
|
ProbDropConn: 0.00,
|
||||||
|
ProbSleep: 0.00,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzConn creates a new FuzzedConnection. Fuzzing starts immediately.
|
||||||
|
func FuzzConn(conn net.Conn) net.Conn {
|
||||||
|
return FuzzConnFromConfig(conn, DefaultFuzzConnConfig())
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzConnFromConfig creates a new FuzzedConnection from a config. Fuzzing
|
||||||
|
// starts immediately.
|
||||||
|
func FuzzConnFromConfig(conn net.Conn, config *FuzzConnConfig) net.Conn {
|
||||||
|
return &FuzzedConnection{
|
||||||
|
conn: conn,
|
||||||
|
start: make(<-chan time.Time),
|
||||||
|
active: true,
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzConnAfter creates a new FuzzedConnection. Fuzzing starts when the
|
||||||
|
// duration elapses.
|
||||||
|
func FuzzConnAfter(conn net.Conn, d time.Duration) net.Conn {
|
||||||
|
return FuzzConnAfterFromConfig(conn, d, DefaultFuzzConnConfig())
|
||||||
|
}
|
||||||
|
|
||||||
|
// FuzzConnAfterFromConfig creates a new FuzzedConnection from a config.
|
||||||
|
// Fuzzing starts when the duration elapses.
|
||||||
|
func FuzzConnAfterFromConfig(conn net.Conn, d time.Duration, config *FuzzConnConfig) net.Conn {
|
||||||
|
return &FuzzedConnection{
|
||||||
|
conn: conn,
|
||||||
|
start: time.After(d),
|
||||||
|
active: false,
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config returns the connection's config.
|
||||||
|
func (fc *FuzzedConnection) Config() *FuzzConnConfig {
|
||||||
|
return fc.config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) Read(data []byte) (n int, err error) {
|
||||||
|
if fc.fuzz() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return fc.conn.Read(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) Write(data []byte) (n int, err error) {
|
||||||
|
if fc.fuzz() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return fc.conn.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) Close() error { return fc.conn.Close() }
|
||||||
|
|
||||||
|
// LocalAddr implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) LocalAddr() net.Addr { return fc.conn.LocalAddr() }
|
||||||
|
|
||||||
|
// RemoteAddr implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) RemoteAddr() net.Addr { return fc.conn.RemoteAddr() }
|
||||||
|
|
||||||
|
// SetDeadline implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) SetDeadline(t time.Time) error { return fc.conn.SetDeadline(t) }
|
||||||
|
|
||||||
|
// SetReadDeadline implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) SetReadDeadline(t time.Time) error {
|
||||||
|
return fc.conn.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline implements net.Conn.
|
||||||
|
func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error {
|
||||||
|
return fc.conn.SetWriteDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FuzzedConnection) randomDuration() time.Duration {
|
func (fc *FuzzedConnection) randomDuration() time.Duration {
|
||||||
maxDelayMillis := int(fc.maxDelay.Nanoseconds() / 1000)
|
maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000)
|
||||||
return time.Millisecond * time.Duration(rand.Int()%maxDelayMillis)
|
return time.Millisecond * time.Duration(rand.Int()%maxDelayMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FuzzedConnection) SetMode(mode int) {
|
|
||||||
switch mode {
|
|
||||||
case FuzzModeDrop:
|
|
||||||
fc.mode = FuzzModeDrop
|
|
||||||
case FuzzModeDelay:
|
|
||||||
fc.mode = FuzzModeDelay
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("Unknown mode %d", mode))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fc *FuzzedConnection) SetProbDropRW(prob float64) {
|
|
||||||
fc.probDropRW = prob
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fc *FuzzedConnection) SetProbDropConn(prob float64) {
|
|
||||||
fc.probDropConn = prob
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fc *FuzzedConnection) SetProbSleep(prob float64) {
|
|
||||||
fc.probSleep = prob
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fc *FuzzedConnection) SetMaxDelay(d time.Duration) {
|
|
||||||
fc.maxDelay = d
|
|
||||||
}
|
|
||||||
|
|
||||||
// implements the fuzz (delay, kill conn)
|
// implements the fuzz (delay, kill conn)
|
||||||
// and returns whether or not the read/write should be ignored
|
// and returns whether or not the read/write should be ignored
|
||||||
func (fc *FuzzedConnection) fuzz() bool {
|
func (fc *FuzzedConnection) fuzz() bool {
|
||||||
|
@ -122,18 +134,18 @@ func (fc *FuzzedConnection) fuzz() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch fc.mode {
|
switch fc.config.Mode {
|
||||||
case FuzzModeDrop:
|
case FuzzModeDrop:
|
||||||
// randomly drop the r/w, drop the conn, or sleep
|
// randomly drop the r/w, drop the conn, or sleep
|
||||||
r := rand.Float64()
|
r := rand.Float64()
|
||||||
if r <= fc.probDropRW {
|
if r <= fc.config.ProbDropRW {
|
||||||
return true
|
return true
|
||||||
} else if r < fc.probDropRW+fc.probDropConn {
|
} else if r < fc.config.ProbDropRW+fc.config.ProbDropConn {
|
||||||
// XXX: can't this fail because machine precision?
|
// XXX: can't this fail because machine precision?
|
||||||
// XXX: do we need an error?
|
// XXX: do we need an error?
|
||||||
fc.Close()
|
fc.Close()
|
||||||
return true
|
return true
|
||||||
} else if r < fc.probDropRW+fc.probDropConn+fc.probSleep {
|
} else if r < fc.config.ProbDropRW+fc.config.ProbDropConn+fc.config.ProbSleep {
|
||||||
time.Sleep(fc.randomDuration())
|
time.Sleep(fc.randomDuration())
|
||||||
}
|
}
|
||||||
case FuzzModeDelay:
|
case FuzzModeDelay:
|
||||||
|
@ -143,7 +155,6 @@ func (fc *FuzzedConnection) fuzz() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't fuzz until start chan fires
|
|
||||||
func (fc *FuzzedConnection) shouldFuzz() bool {
|
func (fc *FuzzedConnection) shouldFuzz() bool {
|
||||||
if fc.active {
|
if fc.active {
|
||||||
return true
|
return true
|
||||||
|
@ -160,31 +171,3 @@ func (fc *FuzzedConnection) shouldFuzz() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read implements net.Conn
|
|
||||||
func (fc *FuzzedConnection) Read(data []byte) (n int, err error) {
|
|
||||||
if fc.fuzz() {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return fc.conn.Read(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write implements net.Conn
|
|
||||||
func (fc *FuzzedConnection) Write(data []byte) (n int, err error) {
|
|
||||||
if fc.fuzz() {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return fc.conn.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements net.Conn
|
|
||||||
func (fc *FuzzedConnection) Close() error { return fc.conn.Close() }
|
|
||||||
func (fc *FuzzedConnection) LocalAddr() net.Addr { return fc.conn.LocalAddr() }
|
|
||||||
func (fc *FuzzedConnection) RemoteAddr() net.Addr { return fc.conn.RemoteAddr() }
|
|
||||||
func (fc *FuzzedConnection) SetDeadline(t time.Time) error { return fc.conn.SetDeadline(t) }
|
|
||||||
func (fc *FuzzedConnection) SetReadDeadline(t time.Time) error {
|
|
||||||
return fc.conn.SetReadDeadline(t)
|
|
||||||
}
|
|
||||||
func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error {
|
|
||||||
return fc.conn.SetWriteDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
2
peer.go
2
peer.go
|
@ -52,7 +52,7 @@ func defaultPeerConfig() *PeerConfig {
|
||||||
HandshakeTimeout: 20 * time.Second,
|
HandshakeTimeout: 20 * time.Second,
|
||||||
DialTimeout: 3 * time.Second,
|
DialTimeout: 3 * time.Second,
|
||||||
MConfig: defaultMConnectionConfig(),
|
MConfig: defaultMConnectionConfig(),
|
||||||
FuzzConfig: defaultFuzzConnConfig(),
|
FuzzConfig: DefaultFuzzConnConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue