mirror of
https://github.com/soypat/lneto.git
synced 2026-07-26 10:38:47 +00:00
lneto rework: Require explicit BackoffStrategy in all APIs (#116)
* make backoff explicit API * fix tests to use explicit backoff * fix examples with explicit tcp
This commit is contained in:
+159
-2
@@ -1,4 +1,161 @@
|
|||||||
|
// Code generated by "stringer -type=MsgType,ClientState,OptCode,StatusCode,DUIDType -linecomment -output stringers.go"; DO NOT EDIT.
|
||||||
|
|
||||||
package dhcpv6
|
package dhcpv6
|
||||||
|
|
||||||
// Code generated by "stringer -type=MsgType,ClientState,OptCode,StatusCode,DUIDType -linecomment -output stringers.go"; DO NOT EDIT.
|
import "strconv"
|
||||||
// Run go generate ./dhcp/dhcpv6/ to regenerate.
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[MsgSolicit-1]
|
||||||
|
_ = x[MsgAdvertise-2]
|
||||||
|
_ = x[MsgRequest-3]
|
||||||
|
_ = x[MsgConfirm-4]
|
||||||
|
_ = x[MsgRenew-5]
|
||||||
|
_ = x[MsgRebind-6]
|
||||||
|
_ = x[MsgReply-7]
|
||||||
|
_ = x[MsgRelease-8]
|
||||||
|
_ = x[MsgDecline-9]
|
||||||
|
_ = x[MsgReconfigure-10]
|
||||||
|
_ = x[MsgInformRequest-11]
|
||||||
|
_ = x[MsgRelayForw-12]
|
||||||
|
_ = x[MsgRelayRepl-13]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _MsgType_name = "solicitadvertiserequestconfirmrenewrebindreplyreleasedeclinereconfigureinform-requestrelay-forwrelay-repl"
|
||||||
|
|
||||||
|
var _MsgType_index = [...]uint8{0, 7, 16, 23, 30, 35, 41, 46, 53, 60, 71, 85, 95, 105}
|
||||||
|
|
||||||
|
func (i MsgType) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i >= MsgType(len(_MsgType_index)-1) {
|
||||||
|
return "MsgType(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||||
|
}
|
||||||
|
return _MsgType_name[_MsgType_index[i]:_MsgType_index[i+1]]
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[StateInit-1]
|
||||||
|
_ = x[StateSoliciting-2]
|
||||||
|
_ = x[StateRequesting-3]
|
||||||
|
_ = x[StateBound-4]
|
||||||
|
_ = x[StateRenewing-5]
|
||||||
|
_ = x[StateRebinding-6]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _ClientState_name = "initsolicitingrequestingboundrenewingrebinding"
|
||||||
|
|
||||||
|
var _ClientState_index = [...]uint8{0, 4, 14, 24, 29, 37, 46}
|
||||||
|
|
||||||
|
func (i ClientState) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i >= ClientState(len(_ClientState_index)-1) {
|
||||||
|
return "ClientState(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||||
|
}
|
||||||
|
return _ClientState_name[_ClientState_index[i]:_ClientState_index[i+1]]
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[OptClientID-1]
|
||||||
|
_ = x[OptServerID-2]
|
||||||
|
_ = x[OptIANA-3]
|
||||||
|
_ = x[OptIATA-4]
|
||||||
|
_ = x[OptIAAddr-5]
|
||||||
|
_ = x[OptORO-6]
|
||||||
|
_ = x[OptPreference-7]
|
||||||
|
_ = x[OptElapsedTime-8]
|
||||||
|
_ = x[OptRelayMsg-9]
|
||||||
|
_ = x[OptAuth-11]
|
||||||
|
_ = x[OptUnicast-12]
|
||||||
|
_ = x[OptStatusCode-13]
|
||||||
|
_ = x[OptRapidCommit-14]
|
||||||
|
_ = x[OptUserClass-15]
|
||||||
|
_ = x[OptVendorClass-16]
|
||||||
|
_ = x[OptVendorOpts-17]
|
||||||
|
_ = x[OptInterfaceID-18]
|
||||||
|
_ = x[OptReconfMsg-19]
|
||||||
|
_ = x[OptReconfAccept-20]
|
||||||
|
_ = x[OptDNSServers-23]
|
||||||
|
_ = x[OptDomainList-24]
|
||||||
|
_ = x[OptIAPD-25]
|
||||||
|
_ = x[OptIAPrefix-26]
|
||||||
|
_ = x[OptNTPServer-56]
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_OptCode_name_0 = "client-idserver-idia-naia-taiaaddroropreferenceelapsed-timerelay-msg"
|
||||||
|
_OptCode_name_1 = "authunicaststatus-coderapid-commituser-classvendor-classvendor-optsinterface-idreconf-msgreconf-accept"
|
||||||
|
_OptCode_name_2 = "dns-serversdomain-listia-pdiaprefix"
|
||||||
|
_OptCode_name_3 = "ntp-server"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_OptCode_index_0 = [...]uint8{0, 9, 18, 23, 28, 34, 37, 47, 59, 68}
|
||||||
|
_OptCode_index_1 = [...]uint8{0, 4, 11, 22, 34, 44, 56, 67, 79, 89, 102}
|
||||||
|
_OptCode_index_2 = [...]uint8{0, 11, 22, 27, 35}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i OptCode) String() string {
|
||||||
|
switch {
|
||||||
|
case 1 <= i && i <= 9:
|
||||||
|
i -= 1
|
||||||
|
return _OptCode_name_0[_OptCode_index_0[i]:_OptCode_index_0[i+1]]
|
||||||
|
case 11 <= i && i <= 20:
|
||||||
|
i -= 11
|
||||||
|
return _OptCode_name_1[_OptCode_index_1[i]:_OptCode_index_1[i+1]]
|
||||||
|
case 23 <= i && i <= 26:
|
||||||
|
i -= 23
|
||||||
|
return _OptCode_name_2[_OptCode_index_2[i]:_OptCode_index_2[i+1]]
|
||||||
|
case i == 56:
|
||||||
|
return _OptCode_name_3
|
||||||
|
default:
|
||||||
|
return "OptCode(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[StatusSuccess-0]
|
||||||
|
_ = x[StatusUnspecFail-1]
|
||||||
|
_ = x[StatusNoAddrsAvail-2]
|
||||||
|
_ = x[StatusNoBinding-3]
|
||||||
|
_ = x[StatusNotOnLink-4]
|
||||||
|
_ = x[StatusUseMulticast-5]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _StatusCode_name = "successunspec-failno-addrs-availno-bindingnot-on-linkuse-multicast"
|
||||||
|
|
||||||
|
var _StatusCode_index = [...]uint8{0, 7, 18, 32, 42, 53, 66}
|
||||||
|
|
||||||
|
func (i StatusCode) String() string {
|
||||||
|
if i >= StatusCode(len(_StatusCode_index)-1) {
|
||||||
|
return "StatusCode(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _StatusCode_name[_StatusCode_index[i]:_StatusCode_index[i+1]]
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[DUIDTypeLLT-1]
|
||||||
|
_ = x[DUIDTypeEN-2]
|
||||||
|
_ = x[DUIDTypeLL-3]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _DUIDType_name = "duid-lltduid-enduid-ll"
|
||||||
|
|
||||||
|
var _DUIDType_index = [...]uint8{0, 8, 15, 22}
|
||||||
|
|
||||||
|
func (i DUIDType) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i >= DUIDType(len(_DUIDType_index)-1) {
|
||||||
|
return "DUIDType(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||||
|
}
|
||||||
|
return _DUIDType_name[_DUIDType_index[i]:_DUIDType_index[i+1]]
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ const (
|
|||||||
ErrMismatch // mismatch
|
ErrMismatch // mismatch
|
||||||
ErrMismatchLen // mismatched length
|
ErrMismatchLen // mismatched length
|
||||||
ErrInvalidConfig // invalid configuration
|
ErrInvalidConfig // invalid configuration
|
||||||
|
_ // little stitious
|
||||||
ErrInvalidField // invalid field
|
ErrInvalidField // invalid field
|
||||||
ErrInvalidLengthField // invalid length field
|
ErrInvalidLengthField // invalid length field
|
||||||
ErrExhausted // resource exhausted
|
ErrExhausted // resource exhausted
|
||||||
ErrAlreadyRegistered // protocol already registered
|
ErrAlreadyRegistered // protocol already registered
|
||||||
ErrTruncatedFrame // truncated frame
|
ErrTruncatedFrame // truncated frame
|
||||||
|
ErrMissingHALConfig // missing HAL configuration
|
||||||
// Below are potentially good future error additions
|
// Below are potentially good future error additions
|
||||||
// based on one or two encountered use cases, example use case included.
|
// based on one or two encountered use cases, example use case included.
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ func run() error {
|
|||||||
RxBufSize: mtu,
|
RxBufSize: mtu,
|
||||||
EstablishedTimeout: 5 * time.Second,
|
EstablishedTimeout: 5 * time.Second,
|
||||||
ClosingTimeout: 5 * time.Second,
|
ClosingTimeout: 5 * time.Second,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return tcpBackoff },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -408,3 +409,15 @@ func stackBackoff(consecutiveBackoffs uint) time.Duration {
|
|||||||
}
|
}
|
||||||
return 10 * time.Millisecond
|
return 10 * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tcpBackoff(consecutiveBackoffs uint) time.Duration {
|
||||||
|
const (
|
||||||
|
minWait = uint32(time.Microsecond)
|
||||||
|
maxWait = 5 * uint32(time.Millisecond)
|
||||||
|
maxShift = 22
|
||||||
|
_overflowCheck = minWait << maxShift
|
||||||
|
)
|
||||||
|
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
||||||
|
wait := min(shifted, maxWait)
|
||||||
|
return time.Duration(wait)
|
||||||
|
}
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ func run() (err error) {
|
|||||||
RxBuf: make([]byte, mtu),
|
RxBuf: make([]byte, mtu),
|
||||||
TxBuf: make([]byte, mtu),
|
TxBuf: make([]byte, mtu),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
|
RWBackoff: tcpBackoff,
|
||||||
})
|
})
|
||||||
err = stack.ListenTCP4(&conn, svPort)
|
err = stack.ListenTCP4(&conn, svPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -363,3 +364,15 @@ func stackBackoff(consecutiveBackoffs uint) time.Duration {
|
|||||||
}
|
}
|
||||||
return 10 * time.Millisecond
|
return 10 * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tcpBackoff(consecutiveBackoffs uint) time.Duration {
|
||||||
|
const (
|
||||||
|
minWait = uint32(time.Microsecond)
|
||||||
|
maxWait = 5 * uint32(time.Millisecond)
|
||||||
|
maxShift = 22
|
||||||
|
_overflowCheck = minWait << maxShift
|
||||||
|
)
|
||||||
|
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
||||||
|
wait := min(shifted, maxWait)
|
||||||
|
return time.Duration(wait)
|
||||||
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ func run(ctx context.Context, stack *xnet.StackAsync) error {
|
|||||||
NanoTime: nanotime,
|
NanoTime: nanotime,
|
||||||
EstablishedTimeout: tcpEstablishedTimeout,
|
EstablishedTimeout: tcpEstablishedTimeout,
|
||||||
ClosingTimeout: tcpCloseTimeout,
|
ClosingTimeout: tcpCloseTimeout,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return tcpBackoff },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -178,3 +179,15 @@ func stackBackoff(consecutiveBackoffs uint) time.Duration {
|
|||||||
}
|
}
|
||||||
return 10 * time.Millisecond
|
return 10 * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tcpBackoff(consecutiveBackoffs uint) time.Duration {
|
||||||
|
const (
|
||||||
|
minWait = uint32(time.Microsecond)
|
||||||
|
maxWait = 5 * uint32(time.Millisecond)
|
||||||
|
maxShift = 22
|
||||||
|
_overflowCheck = minWait << maxShift
|
||||||
|
)
|
||||||
|
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
||||||
|
wait := min(shifted, maxWait)
|
||||||
|
return time.Duration(wait)
|
||||||
|
}
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ func run() (err error) {
|
|||||||
RxBuf: make([]byte, mtu),
|
RxBuf: make([]byte, mtu),
|
||||||
TxBuf: make([]byte, mtu),
|
TxBuf: make([]byte, mtu),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
|
RWBackoff: tcpBackoff,
|
||||||
})
|
})
|
||||||
|
|
||||||
timeHTTPCreate := timer("create HTTP GET request")
|
timeHTTPCreate := timer("create HTTP GET request")
|
||||||
@@ -393,3 +394,14 @@ func stackBackoff(consecutiveBackoffs uint) time.Duration {
|
|||||||
}
|
}
|
||||||
return 10 * time.Millisecond
|
return 10 * time.Millisecond
|
||||||
}
|
}
|
||||||
|
func tcpBackoff(consecutiveBackoffs uint) time.Duration {
|
||||||
|
const (
|
||||||
|
minWait = uint32(time.Microsecond)
|
||||||
|
maxWait = 5 * uint32(time.Millisecond)
|
||||||
|
maxShift = 22
|
||||||
|
_overflowCheck = minWait << maxShift
|
||||||
|
)
|
||||||
|
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
||||||
|
wait := min(shifted, maxWait)
|
||||||
|
return time.Duration(wait)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BackoffConnRW implements exponential backoff suitable for TCP connection
|
|
||||||
// read/write polling. It starts at 1us and caps at 5ms, doubling on each consecutive backoff.
|
|
||||||
func BackoffConnRW(consecutiveBackoffs uint) {
|
|
||||||
const (
|
|
||||||
minWait = uint32(time.Microsecond)
|
|
||||||
maxWait = 5 * uint32(time.Millisecond)
|
|
||||||
maxShift = 22
|
|
||||||
_overflowCheck = minWait << maxShift
|
|
||||||
)
|
|
||||||
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
|
||||||
wait := min(shifted, maxWait)
|
|
||||||
time.Sleep(time.Duration(wait))
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackoffStackProto implements exponential backoff suitable for stack-level
|
|
||||||
// protocol processing polling. It starts at 1us and caps at 100ms, doubling on each consecutive backoff.
|
|
||||||
func BackoffStackProto(consecutiveBackoffs uint) {
|
|
||||||
const (
|
|
||||||
minWait = uint32(time.Microsecond)
|
|
||||||
maxWait = 100 * uint32(time.Millisecond)
|
|
||||||
|
|
||||||
// Statically calculated numbers below.
|
|
||||||
maxShift = 22
|
|
||||||
_overflowCheck = minWait << maxShift
|
|
||||||
)
|
|
||||||
shifted := minWait << min(consecutiveBackoffs, maxShift)
|
|
||||||
wait := min(shifted, maxWait)
|
|
||||||
time.Sleep(time.Duration(wait))
|
|
||||||
}
|
|
||||||
@@ -25,11 +25,12 @@ func _() {
|
|||||||
_ = x[FieldClassBinaryText-14]
|
_ = x[FieldClassBinaryText-14]
|
||||||
_ = x[FieldClassOperation-15]
|
_ = x[FieldClassOperation-15]
|
||||||
_ = x[FieldClassTimestamp-16]
|
_ = x[FieldClassTimestamp-16]
|
||||||
|
_ = x[FieldClassDNSName-17]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _FieldClass_name = "undefinedsourcedestinationprotocolversiontypesizeflagsidentificationchecksumoptionspayloadtextaddressbinary-textoptimestamp"
|
const _FieldClass_name = "undefinedsourcedestinationprotocolversiontypesizeflagsidentificationchecksumoptionspayloadtextaddressbinary-textoptimestampdns name"
|
||||||
|
|
||||||
var _FieldClass_index = [...]uint8{0, 9, 15, 26, 34, 41, 45, 49, 54, 68, 76, 83, 90, 94, 101, 112, 114, 123}
|
var _FieldClass_index = [...]uint8{0, 9, 15, 26, 34, 41, 45, 49, 54, 68, 76, 83, 90, 94, 101, 112, 114, 123, 131}
|
||||||
|
|
||||||
func (i FieldClass) String() string {
|
func (i FieldClass) String() string {
|
||||||
if i >= FieldClass(len(_FieldClass_index)-1) {
|
if i >= FieldClass(len(_FieldClass_index)-1) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/soypat/lneto"
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/tcp"
|
"github.com/soypat/lneto/tcp"
|
||||||
@@ -146,6 +147,7 @@ func setupClientServer6(t *testing.T, rng *rand.Rand, client, server *StackIPv6,
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -154,6 +156,7 @@ func setupClientServer6(t *testing.T, rng *rand.Rand, client, server *StackIPv6,
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -187,6 +190,7 @@ func setupClientServer(t *testing.T, rng *rand.Rand, client, server *StackIPv4,
|
|||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -196,6 +200,7 @@ func setupClientServer(t *testing.T, rng *rand.Rand, client, server *StackIPv4,
|
|||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -219,3 +224,7 @@ func setupClientServer(t *testing.T, rng *rand.Rand, client, server *StackIPv4,
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func backoffYield(consecutiveBackoffs uint) time.Duration {
|
||||||
|
return lneto.BackoffFlagGosched
|
||||||
|
}
|
||||||
|
|||||||
@@ -616,6 +616,7 @@ func setupClient(t *testing.T, client *StackIPv4, conn *tcp.Conn, serverAddr net
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 3,
|
TxPacketQueueSize: 3,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -649,6 +650,7 @@ func newMockTCPPool(n, queuesize, bufsize int) *mockTCPPool {
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: queuesize,
|
TxPacketQueueSize: queuesize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ func (i Type) String() string {
|
|||||||
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
|
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
// Re-run the stringer command to generate them again.
|
// Re-run the stringer command to generate them again.
|
||||||
@@ -72,7 +71,6 @@ func (i CodeDestinationUnreachable) String() string {
|
|||||||
}
|
}
|
||||||
return _CodeDestinationUnreachable_name[_CodeDestinationUnreachable_index[i]:_CodeDestinationUnreachable_index[i+1]]
|
return _CodeDestinationUnreachable_name[_CodeDestinationUnreachable_index[i]:_CodeDestinationUnreachable_index[i+1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
// Re-run the stringer command to generate them again.
|
// Re-run the stringer command to generate them again.
|
||||||
|
|||||||
+23
-11
@@ -206,21 +206,33 @@ func _() {
|
|||||||
_ = x[ErrMismatch-10]
|
_ = x[ErrMismatch-10]
|
||||||
_ = x[ErrMismatchLen-11]
|
_ = x[ErrMismatchLen-11]
|
||||||
_ = x[ErrInvalidConfig-12]
|
_ = x[ErrInvalidConfig-12]
|
||||||
_ = x[ErrInvalidField-13]
|
_ = x[ErrInvalidField-14]
|
||||||
_ = x[ErrInvalidLengthField-14]
|
_ = x[ErrInvalidLengthField-15]
|
||||||
_ = x[ErrExhausted-15]
|
_ = x[ErrExhausted-16]
|
||||||
_ = x[ErrAlreadyRegistered-16]
|
_ = x[ErrAlreadyRegistered-17]
|
||||||
_ = x[ErrTruncatedFrame-17]
|
_ = x[ErrTruncatedFrame-18]
|
||||||
|
_ = x[ErrMissingHALConfig-19]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _errGeneric_name = "lneto-bug(use build tag \"debugheaplog\")packet droppedincorrect checksumzero source(port/addr)zero destination(port/addr)short bufferbuffer fullinvalid addressunsupportedmismatchmismatched lengthinvalid configurationinvalid fieldinvalid length fieldresource exhaustedprotocol already registeredtruncated frame"
|
const (
|
||||||
|
_errGeneric_name_0 = "lneto-bug(use build tag \"debugheaplog\")packet droppedincorrect checksumzero source(port/addr)zero destination(port/addr)short bufferbuffer fullinvalid addressunsupportedmismatchmismatched lengthinvalid configuration"
|
||||||
|
_errGeneric_name_1 = "invalid fieldinvalid length fieldresource exhaustedprotocol already registeredtruncated framemissing HAL configuration"
|
||||||
|
)
|
||||||
|
|
||||||
var _errGeneric_index = [...]uint16{0, 39, 53, 71, 93, 120, 132, 143, 158, 169, 177, 194, 215, 228, 248, 266, 293, 308}
|
var (
|
||||||
|
_errGeneric_index_0 = [...]uint8{0, 39, 53, 71, 93, 120, 132, 143, 158, 169, 177, 194, 215}
|
||||||
|
_errGeneric_index_1 = [...]uint8{0, 13, 33, 51, 78, 93, 118}
|
||||||
|
)
|
||||||
|
|
||||||
func (i errGeneric) String() string {
|
func (i errGeneric) String() string {
|
||||||
i -= 1
|
switch {
|
||||||
if i >= errGeneric(len(_errGeneric_index)-1) {
|
case 1 <= i && i <= 12:
|
||||||
return "errGeneric(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
i -= 1
|
||||||
|
return _errGeneric_name_0[_errGeneric_index_0[i]:_errGeneric_index_0[i+1]]
|
||||||
|
case 14 <= i && i <= 19:
|
||||||
|
i -= 14
|
||||||
|
return _errGeneric_name_1[_errGeneric_index_1[i]:_errGeneric_index_1[i+1]]
|
||||||
|
default:
|
||||||
|
return "errGeneric(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
}
|
}
|
||||||
return _errGeneric_name[_errGeneric_index[i]:_errGeneric_index[i+1]]
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -62,6 +62,9 @@ type ConnConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Conn) Configure(config ConnConfig) (err error) {
|
func (conn *Conn) Configure(config ConnConfig) (err error) {
|
||||||
|
if config.RWBackoff == nil {
|
||||||
|
return lneto.ErrMissingHALConfig
|
||||||
|
}
|
||||||
conn.mu.Lock()
|
conn.mu.Lock()
|
||||||
defer conn.mu.Unlock()
|
defer conn.mu.Unlock()
|
||||||
err = conn.h.SetBuffers(config.TxBuf, config.RxBuf, config.TxPacketQueueSize)
|
err = conn.h.SetBuffers(config.TxBuf, config.RxBuf, config.TxPacketQueueSize)
|
||||||
@@ -483,9 +486,5 @@ func (conn *Conn) ConnectionID() *uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Conn) backoff(consecutiveBackoffs uint) {
|
func (conn *Conn) backoff(consecutiveBackoffs uint) {
|
||||||
if conn._backoff != nil {
|
conn._backoff.Do(consecutiveBackoffs)
|
||||||
conn._backoff.Do(consecutiveBackoffs)
|
|
||||||
} else {
|
|
||||||
internal.BackoffConnRW(consecutiveBackoffs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/soypat/lneto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConfiguredConn(t *testing.T) *Conn {
|
func newConfiguredConn(t *testing.T) *Conn {
|
||||||
@@ -14,6 +16,7 @@ func newConfiguredConn(t *testing.T) *Conn {
|
|||||||
RxBuf: make([]byte, 512),
|
RxBuf: make([]byte, 512),
|
||||||
TxBuf: make([]byte, 512),
|
TxBuf: make([]byte, 512),
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -121,6 +124,7 @@ func TestConn_Configure_Twice(t *testing.T) {
|
|||||||
RxBuf: make([]byte, 1024),
|
RxBuf: make([]byte, 1024),
|
||||||
TxBuf: make([]byte, 1024),
|
TxBuf: make([]byte, 1024),
|
||||||
TxPacketQueueSize: 8,
|
TxPacketQueueSize: 8,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("reconfigure should succeed: %v", err)
|
t.Fatalf("reconfigure should succeed: %v", err)
|
||||||
@@ -160,3 +164,7 @@ func TestConn_ImplementsNetConn(t *testing.T) {
|
|||||||
} = conn
|
} = conn
|
||||||
_ = net.ErrClosed
|
_ = net.ErrClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func backoffYield(consecutiveBackoffs uint) time.Duration {
|
||||||
|
return lneto.BackoffFlagGosched
|
||||||
|
}
|
||||||
|
|||||||
+4
-5
@@ -48,6 +48,9 @@ type ConnConfig struct {
|
|||||||
// Configure initializes the connection with the given buffer and queue configuration.
|
// Configure initializes the connection with the given buffer and queue configuration.
|
||||||
// Must be called before [Conn.Open]. Calling Configure on an active connection aborts it.
|
// Must be called before [Conn.Open]. Calling Configure on an active connection aborts it.
|
||||||
func (conn *Conn) Configure(cfg ConnConfig) error {
|
func (conn *Conn) Configure(cfg ConnConfig) error {
|
||||||
|
if cfg.RWBackoff == nil {
|
||||||
|
return lneto.ErrMissingHALConfig
|
||||||
|
}
|
||||||
conn.mu.Lock()
|
conn.mu.Lock()
|
||||||
defer conn.mu.Unlock()
|
defer conn.mu.Unlock()
|
||||||
conn.abort()
|
conn.abort()
|
||||||
@@ -302,11 +305,7 @@ func (conn *Conn) FreeInput() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Conn) backoff(consecutiveBackoffs uint) {
|
func (conn *Conn) backoff(consecutiveBackoffs uint) {
|
||||||
if conn._backoff != nil {
|
conn._backoff.Do(consecutiveBackoffs)
|
||||||
conn._backoff.Do(consecutiveBackoffs)
|
|
||||||
} else {
|
|
||||||
internal.BackoffConnRW(consecutiveBackoffs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Conn) lockPipeConnID() (uint64, error) {
|
func (conn *Conn) lockPipeConnID() (uint64, error) {
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/internal"
|
"github.com/soypat/lneto/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ func newTestConn(t *testing.T) *Conn {
|
|||||||
TxBuf: make([]byte, 256),
|
TxBuf: make([]byte, 256),
|
||||||
RxQueueSize: 4,
|
RxQueueSize: 4,
|
||||||
TxQueueSize: 4,
|
TxQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -239,3 +242,7 @@ func TestConn_FrameOffset(t *testing.T) {
|
|||||||
t.Fatalf("got %q, want %q", string(buf[:n]), "hi")
|
t.Fatalf("got %q, want %q", string(buf[:n]), "hi")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func backoffYield(backoffs uint) time.Duration {
|
||||||
|
return lneto.BackoffFlagGosched
|
||||||
|
}
|
||||||
|
|||||||
+4
-6
@@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/soypat/lneto"
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/internal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// lnetopacketconn is the lneto interpretation of
|
// lnetopacketconn is the lneto interpretation of
|
||||||
@@ -53,6 +52,9 @@ type PacketConnConfig struct {
|
|||||||
// Configure initializes the PacketConn with the given buffer and queue configuration.
|
// Configure initializes the PacketConn with the given buffer and queue configuration.
|
||||||
// Must be called before [PacketConn.Open]. Calling Configure on an active connection aborts it.
|
// Must be called before [PacketConn.Open]. Calling Configure on an active connection aborts it.
|
||||||
func (pc *PacketConn) Configure(cfg PacketConnConfig) error {
|
func (pc *PacketConn) Configure(cfg PacketConnConfig) error {
|
||||||
|
if cfg.RWBackoff == nil {
|
||||||
|
return lneto.ErrMissingHALConfig
|
||||||
|
}
|
||||||
pc.mu.Lock()
|
pc.mu.Lock()
|
||||||
defer pc.mu.Unlock()
|
defer pc.mu.Unlock()
|
||||||
pc.abort()
|
pc.abort()
|
||||||
@@ -243,11 +245,7 @@ func (pc *PacketConn) deadlineExceeded(deadline *time.Time) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pc *PacketConn) backoff(n uint) {
|
func (pc *PacketConn) backoff(n uint) {
|
||||||
if pc._backoff != nil {
|
pc._backoff.Do(n)
|
||||||
pc._backoff.Do(n)
|
|
||||||
} else {
|
|
||||||
internal.BackoffConnRW(n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pc *PacketConn) lockConnID() (uint64, error) {
|
func (pc *PacketConn) lockConnID() (uint64, error) {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/soypat/lneto"
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/dhcp/dhcpv4"
|
"github.com/soypat/lneto/dhcp/dhcpv4"
|
||||||
"github.com/soypat/lneto/internal"
|
|
||||||
"github.com/soypat/lneto/tcp"
|
"github.com/soypat/lneto/tcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,6 +20,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *StackAsync) StackBlocking(stackProtoBackoff lneto.BackoffStrategy) StackBlocking {
|
func (s *StackAsync) StackBlocking(stackProtoBackoff lneto.BackoffStrategy) StackBlocking {
|
||||||
|
if stackProtoBackoff == nil {
|
||||||
|
panic("nil backoff to StackBlocking")
|
||||||
|
}
|
||||||
return StackBlocking{
|
return StackBlocking{
|
||||||
async: s,
|
async: s,
|
||||||
_backoff: stackProtoBackoff,
|
_backoff: stackProtoBackoff,
|
||||||
@@ -206,9 +208,5 @@ func (s StackBlocking) backoff(consecutiveBackoffs uint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func backoff(bo lneto.BackoffStrategy, consecutiveBackoffs uint) {
|
func backoff(bo lneto.BackoffStrategy, consecutiveBackoffs uint) {
|
||||||
if bo != nil {
|
bo.Do(consecutiveBackoffs)
|
||||||
bo.Do(consecutiveBackoffs)
|
|
||||||
} else {
|
|
||||||
internal.BackoffStackProto(consecutiveBackoffs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ type StackGoConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StackAsync) StackGo(stackProtoBackoff lneto.BackoffStrategy, cfg StackGoConfig) StackGo {
|
func (s *StackAsync) StackGo(stackProtoBackoff lneto.BackoffStrategy, cfg StackGoConfig) StackGo {
|
||||||
|
if stackProtoBackoff == nil || cfg.ListenerPoolConfig.NewBackoff == nil {
|
||||||
|
panic("nil backoff to StackGo")
|
||||||
|
}
|
||||||
return s.StackBlocking(stackProtoBackoff).StackGo(cfg)
|
return s.StackBlocking(stackProtoBackoff).StackGo(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,9 +145,11 @@ func (s StackGo) SocketNetip(ctx context.Context, network string, family, sotype
|
|||||||
var conn tcp.Conn
|
var conn tcp.Conn
|
||||||
// DIAL TCP: active connection a.k.a TCP Client branch.
|
// DIAL TCP: active connection a.k.a TCP Client branch.
|
||||||
err = conn.Configure(tcp.ConnConfig{
|
err = conn.Configure(tcp.ConnConfig{
|
||||||
|
// TODO(pato): Eventually add UDP configuration. we use TCP for now for simplicity's sake.
|
||||||
TxBuf: make([]byte, s.plcfg.TxBufSize),
|
TxBuf: make([]byte, s.plcfg.TxBufSize),
|
||||||
RxBuf: make([]byte, s.plcfg.RxBufSize),
|
RxBuf: make([]byte, s.plcfg.RxBufSize),
|
||||||
TxPacketQueueSize: s.plcfg.QueueSize,
|
TxPacketQueueSize: s.plcfg.QueueSize,
|
||||||
|
RWBackoff: s.plcfg.NewBackoff(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *StackAsync) StackRetrying(stackProtoBackoff lneto.BackoffStrategy) StackRetrying {
|
func (s *StackAsync) StackRetrying(stackProtoBackoff lneto.BackoffStrategy) StackRetrying {
|
||||||
|
if stackProtoBackoff == nil {
|
||||||
|
panic("nil backoff to StackRetrying")
|
||||||
|
}
|
||||||
return StackRetrying{
|
return StackRetrying{
|
||||||
block: s.StackBlocking(stackProtoBackoff),
|
block: s.StackBlocking(stackProtoBackoff),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ func newUDPConn6(t testing.TB) *udp.Conn {
|
|||||||
TxBuf: make([]byte, bufSize),
|
TxBuf: make([]byte, bufSize),
|
||||||
RxQueueSize: 4,
|
RxQueueSize: 4,
|
||||||
TxQueueSize: 4,
|
TxQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("UDP Configure:", err)
|
t.Fatal("UDP Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -85,6 +86,7 @@ func newTCPConn6(t testing.TB) *tcp.Conn {
|
|||||||
RxBuf: make([]byte, bufSize),
|
RxBuf: make([]byte, bufSize),
|
||||||
TxBuf: make([]byte, bufSize),
|
TxBuf: make([]byte, bufSize),
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("TCP Configure:", err)
|
t.Fatal("TCP Configure:", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -53,7 +53,7 @@ type TCPPoolConfig struct {
|
|||||||
ClosingTimeout time.Duration
|
ClosingTimeout time.Duration
|
||||||
// NewUserData is used to create user data used for each individual TCP connection and returned on GetTCP.
|
// NewUserData is used to create user data used for each individual TCP connection and returned on GetTCP.
|
||||||
NewUserData func() any
|
NewUserData func() any
|
||||||
// NewBackoff returns the backoff to use for every newly configured TCP connection.
|
// NewBackoff returns the backoff to use for every newly configured TCP connection. Must be non-nil.
|
||||||
// This should always return a static(non-method) function unless you know what you are doing.
|
// This should always return a static(non-method) function unless you know what you are doing.
|
||||||
NewBackoff func() lneto.BackoffStrategy
|
NewBackoff func() lneto.BackoffStrategy
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,8 @@ type TCPPoolConfig struct {
|
|||||||
func NewTCPPool(cfg TCPPoolConfig) (*TCPPool, error) {
|
func NewTCPPool(cfg TCPPoolConfig) (*TCPPool, error) {
|
||||||
if cfg.EstablishedTimeout <= 0 || cfg.ClosingTimeout <= 0 {
|
if cfg.EstablishedTimeout <= 0 || cfg.ClosingTimeout <= 0 {
|
||||||
return nil, lneto.ErrInvalidConfig
|
return nil, lneto.ErrInvalidConfig
|
||||||
|
} else if cfg.NewBackoff == nil {
|
||||||
|
return nil, lneto.ErrMissingHALConfig
|
||||||
}
|
}
|
||||||
n := int(cfg.PoolSize)
|
n := int(cfg.PoolSize)
|
||||||
pool := &TCPPool{
|
pool := &TCPPool{
|
||||||
@@ -84,9 +86,7 @@ func NewTCPPool(cfg TCPPoolConfig) (*TCPPool, error) {
|
|||||||
TxBuf: bufSpace[txOff : txOff+cfg.TxBufSize],
|
TxBuf: bufSpace[txOff : txOff+cfg.TxBufSize],
|
||||||
TxPacketQueueSize: cfg.QueueSize,
|
TxPacketQueueSize: cfg.QueueSize,
|
||||||
Logger: cfg.ConnLogger,
|
Logger: cfg.ConnLogger,
|
||||||
}
|
RWBackoff: cfg.NewBackoff(),
|
||||||
if cfg.NewBackoff != nil {
|
|
||||||
conncfg.RWBackoff = cfg.NewBackoff()
|
|
||||||
}
|
}
|
||||||
err := pool.conns[i].Configure(conncfg)
|
err := pool.conns[i].Configure(conncfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
|
|||||||
RxBufSize: 512,
|
RxBufSize: 512,
|
||||||
EstablishedTimeout: 5 * time.Second,
|
EstablishedTimeout: 5 * time.Second,
|
||||||
ClosingTimeout: 5 * time.Second,
|
ClosingTimeout: 5 * time.Second,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -96,6 +97,7 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
|
|||||||
RxBuf: connBufs[bufOff : bufOff+tcpBufSize],
|
RxBuf: connBufs[bufOff : bufOff+tcpBufSize],
|
||||||
TxBuf: connBufs[bufOff+tcpBufSize : bufOff+2*tcpBufSize],
|
TxBuf: connBufs[bufOff+tcpBufSize : bufOff+2*tcpBufSize],
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("client %d conn configure: %v", i, err)
|
t.Fatalf("client %d conn configure: %v", i, err)
|
||||||
@@ -327,7 +329,7 @@ func testCloseTransmitsPending(tst *tester, s1, s2 *StackAsync, c1, c2 *tcp.Conn
|
|||||||
RxBuf: nil,
|
RxBuf: nil,
|
||||||
TxBuf: make([]byte, tx1Buf),
|
TxBuf: make([]byte, tx1Buf),
|
||||||
TxPacketQueueSize: queueSize,
|
TxPacketQueueSize: queueSize,
|
||||||
RWBackoff: backoffGosched,
|
RWBackoff: backoffYield,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -431,7 +433,3 @@ func testCloseTransmitsPending(tst *tester, s1, s2 *StackAsync, c1, c2 *tcp.Conn
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func backoffGosched(consecutiveBackoffs uint) (sleep time.Duration) {
|
|
||||||
return lneto.BackoffFlagGosched
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 1 + int(uint16(seed1)%10),
|
TxPacketQueueSize: 1 + int(uint16(seed1)%10),
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -326,6 +327,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 1 + int(uint16(seed2)%10),
|
TxPacketQueueSize: 1 + int(uint16(seed2)%10),
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -335,6 +337,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
|
|||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
RxQueueSize: int(1 + uint16(seed1>>32)%10),
|
RxQueueSize: int(1 + uint16(seed1>>32)%10),
|
||||||
TxQueueSize: int(1 + uint16(seed1>>32)%10),
|
TxQueueSize: int(1 + uint16(seed1>>32)%10),
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -344,6 +347,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
|
|||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
RxQueueSize: int(1 + uint16(seed2>>32)%10),
|
RxQueueSize: int(1 + uint16(seed2>>32)%10),
|
||||||
TxQueueSize: int(1 + uint16(seed2>>32)%10),
|
TxQueueSize: int(1 + uint16(seed2>>32)%10),
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/ethernet"
|
"github.com/soypat/lneto/ethernet"
|
||||||
"github.com/soypat/lneto/tcp"
|
"github.com/soypat/lneto/tcp"
|
||||||
)
|
)
|
||||||
@@ -49,6 +50,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
|
|||||||
RxBuf: make([]byte, MTU),
|
RxBuf: make([]byte, MTU),
|
||||||
TxBuf: make([]byte, MTU),
|
TxBuf: make([]byte, MTU),
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -62,6 +64,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
|
|||||||
RxBufSize: MTU,
|
RxBufSize: MTU,
|
||||||
EstablishedTimeout: 10e9,
|
EstablishedTimeout: 10e9,
|
||||||
ClosingTimeout: 10e9,
|
ClosingTimeout: 10e9,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -150,6 +153,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
|
|||||||
RxBufSize: bufsize,
|
RxBufSize: bufsize,
|
||||||
EstablishedTimeout: 10e9,
|
EstablishedTimeout: 10e9,
|
||||||
ClosingTimeout: 10e9,
|
ClosingTimeout: 10e9,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -188,6 +192,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
|
|||||||
RxBuf: make([]byte, bufsize),
|
RxBuf: make([]byte, bufsize),
|
||||||
TxBuf: make([]byte, bufsize),
|
TxBuf: make([]byte, bufsize),
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -239,6 +244,7 @@ func TestListener_Close(t *testing.T) {
|
|||||||
RxBufSize: 512,
|
RxBufSize: 512,
|
||||||
EstablishedTimeout: 10e9,
|
EstablishedTimeout: 10e9,
|
||||||
ClosingTimeout: 10e9,
|
ClosingTimeout: 10e9,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -278,6 +284,7 @@ func TestListener_ResetAfterClose(t *testing.T) {
|
|||||||
RxBufSize: 512,
|
RxBufSize: 512,
|
||||||
EstablishedTimeout: 10e9,
|
EstablishedTimeout: 10e9,
|
||||||
ClosingTimeout: 10e9,
|
ClosingTimeout: 10e9,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/soypat/lneto"
|
||||||
"github.com/soypat/lneto/ethernet"
|
"github.com/soypat/lneto/ethernet"
|
||||||
"github.com/soypat/lneto/ipv4"
|
"github.com/soypat/lneto/ipv4"
|
||||||
"github.com/soypat/lneto/tcp"
|
"github.com/soypat/lneto/tcp"
|
||||||
@@ -73,6 +74,7 @@ func TestStackAsync_ListenerSynAckAddressedToClient(t *testing.T) {
|
|||||||
RxBufSize: mtu,
|
RxBufSize: mtu,
|
||||||
EstablishedTimeout: 10e9,
|
EstablishedTimeout: 10e9,
|
||||||
ClosingTimeout: 10e9,
|
ClosingTimeout: 10e9,
|
||||||
|
NewBackoff: func() lneto.BackoffStrategy { return backoffYield },
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -104,6 +106,7 @@ func TestStackAsync_ListenerSynAckAddressedToClient(t *testing.T) {
|
|||||||
if err = clConn.Configure(tcp.ConnConfig{
|
if err = clConn.Configure(tcp.ConnConfig{
|
||||||
RxBuf: make([]byte, mtu), TxBuf: make([]byte, mtu),
|
RxBuf: make([]byte, mtu), TxBuf: make([]byte, mtu),
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ func newTCPStacks(t testing.TB, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
|
|||||||
RxBuf: buf[:mtu],
|
RxBuf: buf[:mtu],
|
||||||
TxBuf: buf[mtu : mtu*2],
|
TxBuf: buf[mtu : mtu*2],
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -216,6 +217,7 @@ func newTCPStacks(t testing.TB, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
|
|||||||
RxBuf: buf[2*mtu : 3*mtu],
|
RxBuf: buf[2*mtu : 3*mtu],
|
||||||
TxBuf: buf[3*mtu : 4*mtu],
|
TxBuf: buf[3*mtu : 4*mtu],
|
||||||
TxPacketQueueSize: 4,
|
TxPacketQueueSize: 4,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -1045,3 +1047,7 @@ func getTCPFrame(etherFrame []byte) (tcp.Frame, bool) {
|
|||||||
}
|
}
|
||||||
return tfrm, true
|
return tfrm, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func backoffYield(consecutiveBackoffs uint) time.Duration {
|
||||||
|
return lneto.BackoffFlagGosched
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ func TestStackAsyncRegisterListenerUDP_ReceiveData(t *testing.T) {
|
|||||||
if err := pc.Configure(udp.PacketConnConfig{
|
if err := pc.Configure(udp.PacketConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("pc Configure:", err)
|
t.Fatal("pc Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -74,6 +75,7 @@ func TestStackAsyncRegisterListenerUDP_ReceiveData(t *testing.T) {
|
|||||||
if err := conn.Configure(udp.ConnConfig{
|
if err := conn.Configure(udp.ConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("conn Configure:", err)
|
t.Fatal("conn Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -119,6 +121,7 @@ func TestStackAsyncRegisterListenerUDP_ReplyToClient(t *testing.T) {
|
|||||||
if err := pc.Configure(udp.PacketConnConfig{
|
if err := pc.Configure(udp.PacketConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("pc Configure:", err)
|
t.Fatal("pc Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -133,6 +136,7 @@ func TestStackAsyncRegisterListenerUDP_ReplyToClient(t *testing.T) {
|
|||||||
if err := conn.Configure(udp.ConnConfig{
|
if err := conn.Configure(udp.ConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("conn Configure:", err)
|
t.Fatal("conn Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -228,6 +232,7 @@ func TestStackAsyncRegisterListenerUDP_MultiSource(t *testing.T) {
|
|||||||
if err := pc.Configure(udp.PacketConnConfig{
|
if err := pc.Configure(udp.PacketConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("pc Configure:", err)
|
t.Fatal("pc Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -243,6 +248,7 @@ func TestStackAsyncRegisterListenerUDP_MultiSource(t *testing.T) {
|
|||||||
if err := conn1.Configure(udp.ConnConfig{
|
if err := conn1.Configure(udp.ConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("conn1 Configure:", err)
|
t.Fatal("conn1 Configure:", err)
|
||||||
}
|
}
|
||||||
@@ -260,6 +266,7 @@ func TestStackAsyncRegisterListenerUDP_MultiSource(t *testing.T) {
|
|||||||
if err := conn2.Configure(udp.ConnConfig{
|
if err := conn2.Configure(udp.ConnConfig{
|
||||||
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
RxBuf: make([]byte, testUDPBufSize), TxBuf: make([]byte, testUDPBufSize),
|
||||||
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
RxQueueSize: testUDPQueueSize, TxQueueSize: testUDPQueueSize,
|
||||||
|
RWBackoff: backoffYield,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatal("conn2 Configure:", err)
|
t.Fatal("conn2 Configure:", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user