chore: rename and small improvements

This commit is contained in:
Mark Puha 2025-06-12 19:00:36 +02:00
parent e8dc69d407
commit e997fe1def
9 changed files with 130 additions and 174 deletions

View file

@ -1,55 +0,0 @@
package awg
import "fmt"
type TagJunkGeneratorHandler struct {
tagGenerators []TagJunkGenerator
length int
DefaultJunkCount int // Jc
}
func (handler *TagJunkGeneratorHandler) AppendGenerator(generators TagJunkGenerator) {
handler.tagGenerators = append(handler.tagGenerators, generators)
handler.length++
}
func (handler *TagJunkGeneratorHandler) IsDefined() bool {
return len(handler.tagGenerators) > 0
}
// validate that packets were defined consecutively
func (handler *TagJunkGeneratorHandler) Validate() error {
seen := make([]bool, len(handler.tagGenerators))
for _, generator := range handler.tagGenerators {
index, err := generator.nameIndex()
if index > len(handler.tagGenerators) {
return fmt.Errorf("junk packet index should be consecutive")
}
if err != nil {
return fmt.Errorf("name index: %w", err)
} else {
seen[index-1] = true
}
}
for _, found := range seen {
if !found {
return fmt.Errorf("junk packet index should be consecutive")
}
}
return nil
}
func (handler *TagJunkGeneratorHandler) GeneratePackets() [][]byte {
var rv = make([][]byte, 0, handler.length+handler.DefaultJunkCount)
for i, tagGenerator := range handler.tagGenerators {
PacketCounter.Inc()
rv = append(rv, make([]byte, tagGenerator.packetSize))
copy(rv[i], tagGenerator.generatePacket())
}
PacketCounter.Add(uint64(handler.DefaultJunkCount))
return rv
}

View file

@ -5,22 +5,22 @@ import (
"strconv" "strconv"
) )
type TagJunkGenerator struct { type TagJunkPacketGenerator struct {
name string name string
packetSize int packetSize int
generators []Generator generators []Generator
} }
func newTagJunkGenerator(name string, size int) TagJunkGenerator { func newTagJunkPacketGenerator(name string, size int) TagJunkPacketGenerator {
return TagJunkGenerator{name: name, generators: make([]Generator, 0, size)} return TagJunkPacketGenerator{name: name, generators: make([]Generator, 0, size)}
} }
func (tg *TagJunkGenerator) append(generator Generator) { func (tg *TagJunkPacketGenerator) append(generator Generator) {
tg.generators = append(tg.generators, generator) tg.generators = append(tg.generators, generator)
tg.packetSize += generator.Size() tg.packetSize += generator.Size()
} }
func (tg *TagJunkGenerator) generatePacket() []byte { func (tg *TagJunkPacketGenerator) generatePacket() []byte {
packet := make([]byte, 0, tg.packetSize) packet := make([]byte, 0, tg.packetSize)
for _, generator := range tg.generators { for _, generator := range tg.generators {
packet = append(packet, generator.Generate()...) packet = append(packet, generator.Generate()...)
@ -29,11 +29,11 @@ func (tg *TagJunkGenerator) generatePacket() []byte {
return packet return packet
} }
func (tg *TagJunkGenerator) Name() string { func (tg *TagJunkPacketGenerator) Name() string {
return tg.name return tg.name
} }
func (tg *TagJunkGenerator) nameIndex() (int, error) { func (tg *TagJunkPacketGenerator) nameIndex() (int, error) {
if len(tg.name) != 2 { if len(tg.name) != 2 {
return 0, fmt.Errorf("name must be 2 character long: %s", tg.name) return 0, fmt.Errorf("name must be 2 character long: %s", tg.name)
} }

View file

@ -14,13 +14,13 @@ func TestNewTagJunkGenerator(t *testing.T) {
name string name string
genName string genName string
size int size int
expected TagJunkGenerator expected TagJunkPacketGenerator
}{ }{
{ {
name: "Create new generator with empty name", name: "Create new generator with empty name",
genName: "", genName: "",
size: 0, size: 0,
expected: TagJunkGenerator{ expected: TagJunkPacketGenerator{
name: "", name: "",
packetSize: 0, packetSize: 0,
generators: make([]Generator, 0), generators: make([]Generator, 0),
@ -30,7 +30,7 @@ func TestNewTagJunkGenerator(t *testing.T) {
name: "Create new generator with valid name", name: "Create new generator with valid name",
genName: "T1", genName: "T1",
size: 0, size: 0,
expected: TagJunkGenerator{ expected: TagJunkPacketGenerator{
name: "T1", name: "T1",
packetSize: 0, packetSize: 0,
generators: make([]Generator, 0), generators: make([]Generator, 0),
@ -40,7 +40,7 @@ func TestNewTagJunkGenerator(t *testing.T) {
name: "Create new generator with non-zero size", name: "Create new generator with non-zero size",
genName: "T2", genName: "T2",
size: 5, size: 5,
expected: TagJunkGenerator{ expected: TagJunkPacketGenerator{
name: "T2", name: "T2",
packetSize: 0, packetSize: 0,
generators: make([]Generator, 5), generators: make([]Generator, 5),
@ -52,7 +52,7 @@ func TestNewTagJunkGenerator(t *testing.T) {
tc := tc // capture range variable tc := tc // capture range variable
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
result := newTagJunkGenerator(tc.genName, tc.size) result := newTagJunkPacketGenerator(tc.genName, tc.size)
require.Equal(t, tc.expected.name, result.name) require.Equal(t, tc.expected.name, result.name)
require.Equal(t, tc.expected.packetSize, result.packetSize) require.Equal(t, tc.expected.packetSize, result.packetSize)
require.Len(t, result.generators, len(tc.expected.generators)) require.Len(t, result.generators, len(tc.expected.generators))
@ -65,21 +65,21 @@ func TestTagJunkGeneratorAppend(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
initialState TagJunkGenerator initialState TagJunkPacketGenerator
mockSize int mockSize int
expectedLength int expectedLength int
expectedSize int expectedSize int
}{ }{
{ {
name: "Append to empty generator", name: "Append to empty generator",
initialState: newTagJunkGenerator("T1", 0), initialState: newTagJunkPacketGenerator("T1", 0),
mockSize: 5, mockSize: 5,
expectedLength: 1, expectedLength: 1,
expectedSize: 5, expectedSize: 5,
}, },
{ {
name: "Append to non-empty generator", name: "Append to non-empty generator",
initialState: TagJunkGenerator{name: "T2", packetSize: 10, generators: make([]Generator, 2)}, initialState: TagJunkPacketGenerator{name: "T2", packetSize: 10, generators: make([]Generator, 2)},
mockSize: 7, mockSize: 7,
expectedLength: 3, // 2 existing + 1 new expectedLength: 3, // 2 existing + 1 new
expectedSize: 17, // 10 + 7 expectedSize: 17, // 10 + 7
@ -111,20 +111,20 @@ func TestTagJunkGeneratorGenerate(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
setupGenerator func() TagJunkGenerator setupGenerator func() TagJunkPacketGenerator
expected []byte expected []byte
}{ }{
{ {
name: "Generate with empty generators", name: "Generate with empty generators",
setupGenerator: func() TagJunkGenerator { setupGenerator: func() TagJunkPacketGenerator {
return newTagJunkGenerator("T1", 0) return newTagJunkPacketGenerator("T1", 0)
}, },
expected: []byte{}, expected: []byte{},
}, },
{ {
name: "Generate with single generator", name: "Generate with single generator",
setupGenerator: func() TagJunkGenerator { setupGenerator: func() TagJunkPacketGenerator {
tg := newTagJunkGenerator("T2", 0) tg := newTagJunkPacketGenerator("T2", 0)
tg.append(mockGen1) tg.append(mockGen1)
return tg return tg
}, },
@ -132,8 +132,8 @@ func TestTagJunkGeneratorGenerate(t *testing.T) {
}, },
{ {
name: "Generate with multiple generators", name: "Generate with multiple generators",
setupGenerator: func() TagJunkGenerator { setupGenerator: func() TagJunkPacketGenerator {
tg := newTagJunkGenerator("T3", 0) tg := newTagJunkPacketGenerator("T3", 0)
tg.append(mockGen1) tg.append(mockGen1)
tg.append(mockGen2) tg.append(mockGen2)
return tg return tg
@ -192,7 +192,7 @@ func TestTagJunkGeneratorNameIndex(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
tg := TagJunkGenerator{name: tc.generatorName} tg := TagJunkPacketGenerator{name: tc.generatorName}
index, err := tg.nameIndex() index, err := tg.nameIndex()
if tc.expectError { if tc.expectError {

View file

@ -0,0 +1,55 @@
package awg
import "fmt"
type TagJunkPacketGenerators struct {
tagGenerators []TagJunkPacketGenerator
length int
DefaultJunkCount int // Jc
}
func (generators *TagJunkPacketGenerators) AppendGenerator(generator TagJunkPacketGenerator) {
generators.tagGenerators = append(generators.tagGenerators, generator)
generators.length++
}
func (generators *TagJunkPacketGenerators) IsDefined() bool {
return len(generators.tagGenerators) > 0
}
// validate that packets were defined consecutively
func (generators *TagJunkPacketGenerators) Validate() error {
seen := make([]bool, len(generators.tagGenerators))
for _, generator := range generators.tagGenerators {
index, err := generator.nameIndex()
if index > len(generators.tagGenerators) {
return fmt.Errorf("junk packet index should be consecutive")
}
if err != nil {
return fmt.Errorf("name index: %w", err)
} else {
seen[index-1] = true
}
}
for _, found := range seen {
if !found {
return fmt.Errorf("junk packet index should be consecutive")
}
}
return nil
}
func (generators *TagJunkPacketGenerators) GeneratePackets() [][]byte {
var rv = make([][]byte, 0, generators.length+generators.DefaultJunkCount)
for i, tagGenerator := range generators.tagGenerators {
PacketCounter.Inc()
rv = append(rv, make([]byte, tagGenerator.packetSize))
copy(rv[i], tagGenerator.generatePacket())
}
PacketCounter.Add(uint64(generators.DefaultJunkCount))
return rv
}

View file

@ -10,11 +10,11 @@ import (
func TestTagJunkGeneratorHandlerAppendGenerator(t *testing.T) { func TestTagJunkGeneratorHandlerAppendGenerator(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
generator TagJunkGenerator generator TagJunkPacketGenerator
}{ }{
{ {
name: "append single generator", name: "append single generator",
generator: newTagJunkGenerator("t1", 10), generator: newTagJunkPacketGenerator("t1", 10),
}, },
} }
@ -22,17 +22,17 @@ func TestTagJunkGeneratorHandlerAppendGenerator(t *testing.T) {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel() t.Parallel()
handler := &TagJunkGeneratorHandler{} generators := &TagJunkPacketGenerators{}
// Initial length should be 0 // Initial length should be 0
require.Equal(t, 0, handler.length) require.Equal(t, 0, generators.length)
require.Empty(t, handler.tagGenerators) require.Empty(t, generators.tagGenerators)
// After append, length should be 1 and generator should be added // After append, length should be 1 and generator should be added
handler.AppendGenerator(tt.generator) generators.AppendGenerator(tt.generator)
require.Equal(t, 1, handler.length) require.Equal(t, 1, generators.length)
require.Len(t, handler.tagGenerators, 1) require.Len(t, generators.tagGenerators, 1)
require.Equal(t, tt.generator, handler.tagGenerators[0]) require.Equal(t, tt.generator, generators.tagGenerators[0])
}) })
} }
} }
@ -40,42 +40,42 @@ func TestTagJunkGeneratorHandlerAppendGenerator(t *testing.T) {
func TestTagJunkGeneratorHandlerValidate(t *testing.T) { func TestTagJunkGeneratorHandlerValidate(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
generators []TagJunkGenerator generators []TagJunkPacketGenerator
wantErr bool wantErr bool
errMsg string errMsg string
}{ }{
{ {
name: "bad start", name: "bad start",
generators: []TagJunkGenerator{ generators: []TagJunkPacketGenerator{
newTagJunkGenerator("t3", 10), newTagJunkPacketGenerator("t3", 10),
newTagJunkGenerator("t4", 10), newTagJunkPacketGenerator("t4", 10),
}, },
wantErr: true, wantErr: true,
errMsg: "junk packet index should be consecutive", errMsg: "junk packet index should be consecutive",
}, },
{ {
name: "non-consecutive indices", name: "non-consecutive indices",
generators: []TagJunkGenerator{ generators: []TagJunkPacketGenerator{
newTagJunkGenerator("t1", 10), newTagJunkPacketGenerator("t1", 10),
newTagJunkGenerator("t3", 10), // Missing t2 newTagJunkPacketGenerator("t3", 10), // Missing t2
}, },
wantErr: true, wantErr: true,
errMsg: "junk packet index should be consecutive", errMsg: "junk packet index should be consecutive",
}, },
{ {
name: "consecutive indices", name: "consecutive indices",
generators: []TagJunkGenerator{ generators: []TagJunkPacketGenerator{
newTagJunkGenerator("t1", 10), newTagJunkPacketGenerator("t1", 10),
newTagJunkGenerator("t2", 10), newTagJunkPacketGenerator("t2", 10),
newTagJunkGenerator("t3", 10), newTagJunkPacketGenerator("t3", 10),
newTagJunkGenerator("t4", 10), newTagJunkPacketGenerator("t4", 10),
newTagJunkGenerator("t5", 10), newTagJunkPacketGenerator("t5", 10),
}, },
}, },
{ {
name: "nameIndex error", name: "nameIndex error",
generators: []TagJunkGenerator{ generators: []TagJunkPacketGenerator{
newTagJunkGenerator("error", 10), newTagJunkPacketGenerator("error", 10),
}, },
wantErr: true, wantErr: true,
errMsg: "name must be 2 character long", errMsg: "name must be 2 character long",
@ -86,12 +86,12 @@ func TestTagJunkGeneratorHandlerValidate(t *testing.T) {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel() t.Parallel()
handler := &TagJunkGeneratorHandler{} generators := &TagJunkPacketGenerators{}
for _, gen := range tt.generators { for _, gen := range tt.generators {
handler.AppendGenerator(gen) generators.AppendGenerator(gen)
} }
err := handler.Validate() err := generators.Validate()
if tt.wantErr { if tt.wantErr {
require.Error(t, err) require.Error(t, err)
require.Contains(t, err.Error(), tt.errMsg) require.Contains(t, err.Error(), tt.errMsg)
@ -110,20 +110,20 @@ func TestTagJunkGeneratorHandlerGenerate(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
setupGenerator func() []TagJunkGenerator setupGenerator func() []TagJunkPacketGenerator
expected [][]byte expected [][]byte
}{ }{
{ {
name: "generate with no default junk", name: "generate with no default junk",
setupGenerator: func() []TagJunkGenerator { setupGenerator: func() []TagJunkPacketGenerator {
tg1 := newTagJunkGenerator("t1", 0) tg1 := newTagJunkPacketGenerator("t1", 0)
tg1.append(mockGen1) tg1.append(mockGen1)
tg1.append(mockGen2) tg1.append(mockGen2)
tg2 := newTagJunkGenerator("t2", 0) tg2 := newTagJunkPacketGenerator("t2", 0)
tg2.append(mockGen2) tg2.append(mockGen2)
tg2.append(mockGen1) tg2.append(mockGen1)
return []TagJunkGenerator{tg1, tg2} return []TagJunkPacketGenerator{tg1, tg2}
}, },
expected: [][]byte{ expected: [][]byte{
append(mockByte1, mockByte2...), append(mockByte1, mockByte2...),
@ -136,13 +136,13 @@ func TestTagJunkGeneratorHandlerGenerate(t *testing.T) {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel() t.Parallel()
handler := &TagJunkGeneratorHandler{} generators := &TagJunkPacketGenerators{}
generators := tt.setupGenerator() tagGenerators := tt.setupGenerator()
for _, gen := range generators { for _, gen := range tagGenerators {
handler.AppendGenerator(gen) generators.AppendGenerator(gen)
} }
result := handler.GeneratePackets() result := generators.GeneratePackets()
require.Equal(t, result, tt.expected) require.Equal(t, result, tt.expected)
}) })
} }

View file

@ -54,10 +54,10 @@ func parseTag(input string) (Tag, error) {
} }
// TODO: pointernes // TODO: pointernes
func Parse(name, input string) (TagJunkGenerator, error) { func Parse(name, input string) (TagJunkPacketGenerator, error) {
inputSlice := strings.Split(input, "<") inputSlice := strings.Split(input, "<")
if len(inputSlice) <= 1 { if len(inputSlice) <= 1 {
return TagJunkGenerator{}, fmt.Errorf("empty input: %s", input) return TagJunkPacketGenerator{}, fmt.Errorf("empty input: %s", input)
} }
uniqueTagCheck := make(map[EnumTag]bool, len(uniqueTags)) uniqueTagCheck := make(map[EnumTag]bool, len(uniqueTags))
@ -65,28 +65,28 @@ func Parse(name, input string) (TagJunkGenerator, error) {
// skip byproduct of split // skip byproduct of split
inputSlice = inputSlice[1:] inputSlice = inputSlice[1:]
rv := newTagJunkGenerator(name, len(inputSlice)) rv := newTagJunkPacketGenerator(name, len(inputSlice))
for _, inputParam := range inputSlice { for _, inputParam := range inputSlice {
if len(inputParam) <= 1 { if len(inputParam) <= 1 {
return TagJunkGenerator{}, fmt.Errorf("empty tag in input: %s", inputSlice) return TagJunkPacketGenerator{}, fmt.Errorf("empty tag in input: %s", inputSlice)
} else if strings.Count(inputParam, ">") != 1 { } else if strings.Count(inputParam, ">") != 1 {
return TagJunkGenerator{}, fmt.Errorf("ill formated input: %s", input) return TagJunkPacketGenerator{}, fmt.Errorf("ill formated input: %s", input)
} }
tag, _ := parseTag(inputParam) tag, _ := parseTag(inputParam)
creator, ok := generatorCreator[tag.Name] creator, ok := generatorCreator[tag.Name]
if !ok { if !ok {
return TagJunkGenerator{}, fmt.Errorf("invalid tag: %s", tag.Name) return TagJunkPacketGenerator{}, fmt.Errorf("invalid tag: %s", tag.Name)
} }
if present, ok := uniqueTagCheck[tag.Name]; ok { if present, ok := uniqueTagCheck[tag.Name]; ok {
if present { if present {
return TagJunkGenerator{}, fmt.Errorf("tag %s needs to be unique", tag.Name) return TagJunkPacketGenerator{}, fmt.Errorf("tag %s needs to be unique", tag.Name)
} }
uniqueTagCheck[tag.Name] = true uniqueTagCheck[tag.Name] = true
} }
generator, err := creator(tag.Param) generator, err := creator(tag.Param)
if err != nil { if err != nil {
return TagJunkGenerator{}, fmt.Errorf("gen: %w", err) return TagJunkPacketGenerator{}, fmt.Errorf("gen: %w", err)
} }
// TODO: handle counter tag // TODO: handle counter tag

View file

@ -50,48 +50,7 @@ func uapiCfg(cfg ...string) string {
// genConfigs generates a pair of configs that connect to each other. // genConfigs generates a pair of configs that connect to each other.
// The configs use distinct, probably-usable ports. // The configs use distinct, probably-usable ports.
func genConfigs(tb testing.TB) (cfgs, endpointCfgs [2]string) { func genConfigs(tb testing.TB, cfg ...string) (cfgs, endpointCfgs [2]string) {
var key1, key2 NoisePrivateKey
_, err := rand.Read(key1[:])
if err != nil {
tb.Errorf("unable to generate private key random bytes: %v", err)
}
_, err = rand.Read(key2[:])
if err != nil {
tb.Errorf("unable to generate private key random bytes: %v", err)
}
pub1, pub2 := key1.publicKey(), key2.publicKey()
cfgs[0] = uapiCfg(
"private_key", hex.EncodeToString(key1[:]),
"listen_port", "0",
"replace_peers", "true",
"public_key", hex.EncodeToString(pub2[:]),
"protocol_version", "1",
"replace_allowed_ips", "true",
"allowed_ip", "1.0.0.2/32",
)
endpointCfgs[0] = uapiCfg(
"public_key", hex.EncodeToString(pub2[:]),
"endpoint", "127.0.0.1:%d",
)
cfgs[1] = uapiCfg(
"private_key", hex.EncodeToString(key2[:]),
"listen_port", "0",
"replace_peers", "true",
"public_key", hex.EncodeToString(pub1[:]),
"protocol_version", "1",
"replace_allowed_ips", "true",
"allowed_ip", "1.0.0.1/32",
)
endpointCfgs[1] = uapiCfg(
"public_key", hex.EncodeToString(pub1[:]),
"endpoint", "127.0.0.1:%d",
)
return
}
func genAWGConfigs(tb testing.TB, cfg ...string) (cfgs, endpointCfgs [2]string) {
var key1, key2 NoisePrivateKey var key1, key2 NoisePrivateKey
_, err := rand.Read(key1[:]) _, err := rand.Read(key1[:])
if err != nil { if err != nil {
@ -207,11 +166,8 @@ func genTestPair(
extraCfg ...string, extraCfg ...string,
) (pair testPair) { ) (pair testPair) {
var cfg, endpointCfg [2]string var cfg, endpointCfg [2]string
if len(extraCfg) > 0 { cfg, endpointCfg = genConfigs(tb, extraCfg...)
cfg, endpointCfg = genAWGConfigs(tb, extraCfg...)
} else {
cfg, endpointCfg = genConfigs(tb)
}
var binds [2]conn.Bind var binds [2]conn.Bind
if realSocket { if realSocket {
binds[0], binds[1] = conn.NewDefaultBind(), conn.NewDefaultBind() binds[0], binds[1] = conn.NewDefaultBind(), conn.NewDefaultBind()

View file

@ -145,7 +145,7 @@ func (peer *Peer) SendBuffers(buffers [][]byte) error {
return err return err
} }
func (peer *Peer) SendBuffersCountPacket(buffers [][]byte) error { func (peer *Peer) SendAndCountBuffers(buffers [][]byte) error {
err := peer.SendBuffers(buffers) err := peer.SendBuffers(buffers)
if err == nil { if err == nil {
awg.PacketCounter.Add(uint64(len(buffers))) awg.PacketCounter.Add(uint64(len(buffers)))

View file

@ -190,7 +190,7 @@ func (peer *Peer) SendHandshakeInitiation(isRetry bool) error {
sendBuffer = append(sendBuffer, junkedHeader) sendBuffer = append(sendBuffer, junkedHeader)
err = peer.SendBuffersCountPacket(sendBuffer) err = peer.SendAndCountBuffers(sendBuffer)
if err != nil { if err != nil {
peer.device.log.Errorf("%v - Failed to send handshake initiation: %v", peer, err) peer.device.log.Errorf("%v - Failed to send handshake initiation: %v", peer, err)
} }
@ -246,7 +246,7 @@ func (peer *Peer) SendHandshakeResponse() error {
peer.timersAnyAuthenticatedPacketSent() peer.timersAnyAuthenticatedPacketSent()
// TODO: allocation could be avoided // TODO: allocation could be avoided
err = peer.SendBuffersCountPacket([][]byte{junkedHeader}) err = peer.SendAndCountBuffers([][]byte{junkedHeader})
if err != nil { if err != nil {
peer.device.log.Errorf("%v - Failed to send handshake response: %v", peer, err) peer.device.log.Errorf("%v - Failed to send handshake response: %v", peer, err)
} }
@ -600,7 +600,7 @@ func (peer *Peer) RoutineSequentialSender(maxBatchSize int) {
peer.timersAnyAuthenticatedPacketTraversal() peer.timersAnyAuthenticatedPacketTraversal()
peer.timersAnyAuthenticatedPacketSent() peer.timersAnyAuthenticatedPacketSent()
err := peer.SendBuffersCountPacket(bufs) err := peer.SendAndCountBuffers(bufs)
if dataSent { if dataSent {
peer.timersDataSent() peer.timersDataSent()
} }