Skip to content

Commit

Permalink
packets sequences support in packetgen
Browse files Browse the repository at this point in the history
  • Loading branch information
arriven committed Apr 16, 2022
1 parent fe104aa commit 853980b
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 6 deletions.
22 changes: 22 additions & 0 deletions examples/config/advanced/packetgen-slowloris.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
jobs:
- type: packetgen
args:
connection:
type: net
args:
protocol: "udp"
address: "google.com:1234"
tls_config:
insecure_skip_verify: true
packets:
- packet:
payload:
type: raw
data:
payload: "POST /someapi HTTP/1.1\nHost: localhost\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 1000\n\n"
- count: 1000
packet:
payload:
type: raw
data:
payload: "a"
46 changes: 40 additions & 6 deletions src/job/packetgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (

type packetgenJobConfig struct {
BasicJobConfig
Packet *templates.MapStruct
Packets []*templates.MapStruct
Connection packetgen.ConnectionConfig
}

Expand Down Expand Up @@ -68,13 +68,20 @@ func sendPacket(ctx context.Context, logger *zap.Logger, jobConfig *packetgenJob
ctx, cancel := context.WithCancel(ctx)
defer cancel()

packetsChan := utils.InfiniteRange(ctx, jobConfig.Packets)

conn, err := packetgen.OpenConnection(ctx, jobConfig.Connection)
if err != nil {
return err
}

for jobConfig.Next(ctx) {
packetConfigRaw := jobConfig.Packet.Execute(logger, ctx)
packetTpl, more := <-packetsChan
if !more {
return nil
}

packetConfigRaw := packetTpl.Execute(logger, ctx)
logger.Debug("rendered packet config template", zap.Reflect("config", packetConfigRaw))

var packetConfig packetgen.PacketConfig
Expand Down Expand Up @@ -103,19 +110,46 @@ func sendPacket(ctx context.Context, logger *zap.Logger, jobConfig *packetgenJob
func parsePacketgenArgs(ctx context.Context, args config.Args, globalConfig *GlobalConfig, a *metrics.Accumulator, logger *zap.Logger) (
tpl *packetgenJobConfig, err error,
) {
type packetDescriptor struct {
Packet map[string]any
Count int
}

var jobConfig struct {
BasicJobConfig
Packet map[string]any
Packets []packetDescriptor
Connection packetgen.ConnectionConfig
}

if err = ParseConfig(&jobConfig, args, *globalConfig); err != nil {
return nil, fmt.Errorf("error parsing job config: %w", err)
}

packetTpl, err := templates.ParseMapStruct(jobConfig.Packet)
if err != nil {
return nil, fmt.Errorf("error parsing packet: %w", err)
packetTpls := make([]*templates.MapStruct, 0, len(jobConfig.Packets)+1)

if len(jobConfig.Packets) > 0 {
for _, descriptor := range jobConfig.Packets {
if descriptor.Count < 1 {
descriptor.Count = 1
}

packetTpl, err := templates.ParseMapStruct(descriptor.Packet)
if err != nil {
return nil, fmt.Errorf("error parsing packet: %w", err)
}

for i := 0; i < descriptor.Count; i++ {
packetTpls = append(packetTpls, packetTpl)
}
}
} else {
packetTpl, err := templates.ParseMapStruct(jobConfig.Packet)
if err != nil {
return nil, fmt.Errorf("error parsing packet: %w", err)
}

packetTpls = append(packetTpls, packetTpl)
}

if globalConfig.ProxyURLs != "" && jobConfig.Connection.Args["protocol"] == "tcp" {
Expand All @@ -124,7 +158,7 @@ func parsePacketgenArgs(ctx context.Context, args config.Args, globalConfig *Glo

return &packetgenJobConfig{
BasicJobConfig: jobConfig.BasicJobConfig,
Packet: packetTpl,
Packets: packetTpls,
Connection: jobConfig.Connection,
}, nil
}
23 changes: 23 additions & 0 deletions src/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package utils

import (
"context"
"fmt"
"log"
"os"
Expand Down Expand Up @@ -117,6 +118,28 @@ func Decode(input any, output any) error {
return decoder.Decode(input)
}

// It could've been more effective if go had yield but this should be close enough
func InfiniteRange[T any](ctx context.Context, input []T) chan T {
result := make(chan T)

loop := func() {
defer close(result)

for {
for _, el := range input {
select {
case <-ctx.Done():
return
case result <- el:
}
}
}
}
go loop()

return result
}

func Unmarshal(input []byte, output any, format string) error {
switch format {
case "", "json", "yaml":
Expand Down

0 comments on commit 853980b

Please sign in to comment.