Skip to content

Commit

Permalink
Merge pull request #7 from louisroyer/fix-issue-6
Browse files Browse the repository at this point in the history
Various improvements and bug fixes
  • Loading branch information
shynuu authored Sep 28, 2023
2 parents 9d472a2 + 485ed9e commit 5a973d2
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 133 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*log
Vagrantfile
trunk
trunks
trunks_amd64

# Dependency directories (remove the comment below to include it)
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@ COMMANDS:
help, h Shows a list of commands or help for one command

GLOBAL OPTIONS:
--config FILE Load configuration from FILE (default: not set)
--flush Flush IPTABLES table mangle and clear all TC rules (default: false)
--acm Activate the ACM simulation (default: not activated)
--qos Process traffic using QoS (default: not activated)
--help, -h show help (default: false)
--config FILE Load configuration from FILE (default: not set)
--logs value Log path for the log file (default: not set)
--flush Flush IPTABLES table mangle and clear all TC rules (default: false)
--acm Activate the ACM simulation (default: not activated)
--qos Process traffic using QoS (default: not activated)
--disable-kernel-version-check Disable check for bugged kernel versions (default: kernel version check enabled)
--help, -h show help (default: false)

```

Expand Down Expand Up @@ -149,4 +151,7 @@ cd container
docker-compose up -d
```

You still must configure the routes inside the client and server containers.
You still must configure the routes inside the client and server containers.

## Known issues
Some versions of the kernel are known to crash when offset delay is enabled. As a protection, offset delay is by default disabled if you are running on affected versions. You can bypass protection by using the flag `--disable-kernel-version-check`, but this is NOT recommended. See [this issue](https://github.com/shynuu/trunks/issues/6) for details.
21 changes: 21 additions & 0 deletions bash-completion/completions/trunks
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#! /bin/bash

: ${PROG:=$(basename ${BASH_SOURCE})}

_cli_bash_autocomplete() {
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
local cur opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
if [[ "$cur" == "-"* ]]; then
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion )
else
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
}

complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete $PROG
unset PROG
31 changes: 24 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,33 @@ import (
"fmt"
"log"
"os"
"os/signal"
"syscall"

trunks "github.com/shynuu/trunks/runtime"

"github.com/urfave/cli/v2"
)

// Initialize signals handling
func initSignals() {
cancelChan := make(chan os.Signal, 1)
signal.Notify(cancelChan, syscall.SIGTERM, syscall.SIGINT)
func(_ os.Signal) {}(<-cancelChan)
os.Exit(0)
}

func main() {
var config string
var flush bool = false
var acm bool = false
var qos bool = false
var disable_kernel_version_check = false
var logs string

app := &cli.App{
Name: "trunks",
Usage: "a simple DVB-S2/DVB-RCS2 simulator",
Name: "trunks",
Usage: "a simple DVB-S2/DVB-RCS2 simulator",
EnableBashCompletion: true,
Authors: []*cli.Author{
{Name: "Youssouf Drif"},
},
Expand Down Expand Up @@ -55,27 +66,33 @@ func main() {
Destination: &qos,
DefaultText: "not activated",
},
&cli.BoolFlag{
Name: "disable-kernel-version-check",
Usage: "Disable check for bugged kernel versions",
Destination: &disable_kernel_version_check,
DefaultText: "kernel version check enabled",
},
},
Action: func(c *cli.Context) error {
err := trunks.InitTrunks(config, qos, logs)
trunksConfig, err := trunks.InitTrunks(config, qos, logs, acm, disable_kernel_version_check)
if err != nil {
fmt.Println("Init error, exiting...")
os.Exit(1)
}

if flush {
err = trunks.FlushTables()
err = trunksConfig.FlushTables()
if err != nil {
fmt.Println("Impossible to flush tables, exiting...")
os.Exit(1)
}
}

trunks.Run(acm)
trunksConfig.Run()
return nil
},
}

go initSignals()
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
Expand Down
28 changes: 14 additions & 14 deletions runtime/acm.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,33 @@ import (
)

// RunACM simulate the used by the DVB-S2/RCS2 system
func RunACM(qos bool) {
if Trunks.CurrentACM == nil || Trunks.ACMCounter >= Trunks.CurrentACM.Duration {
func (t *TrunksConfig) RunACM(qos bool) {
if t.CurrentACM == nil || t.ACMCounter >= t.CurrentACM.Duration {
log.Println("Changing link capacity")
var l = len(Trunks.ACMList)
var l = len(t.ACMList)
rand.Seed(time.Now().UnixNano())
var index int = rand.Intn(l)
Trunks.CurrentACM = Trunks.ACMList[index]
t.CurrentACM = t.ACMList[index]

var forward string
var retun string

if qos {
forward = fmt.Sprintf("%dmbit", int64(math.Round(Trunks.Bandwidth.Forward*Trunks.CurrentACM.Weight))-1)
retun = fmt.Sprintf("%dmbit", int64(math.Round(Trunks.Bandwidth.Return*Trunks.CurrentACM.Weight))-1)
runTC("class", "change", "dev", Trunks.NIC.GW, "parent", "1:0", "classid", "1:20", "htb", "rate", retun, "prio", "1")
runTC("class", "change", "dev", Trunks.NIC.ST, "parent", "1:0", "classid", "1:20", "htb", "rate", forward, "prio", "1")
forward = fmt.Sprintf("%dmbit", int64(math.Round(t.Bandwidth.Forward*t.CurrentACM.Weight))-1)
retun = fmt.Sprintf("%dmbit", int64(math.Round(t.Bandwidth.Return*t.CurrentACM.Weight))-1)
runTC("class", "change", "dev", t.NIC.GW, "parent", "1:0", "classid", "1:20", "htb", "rate", retun, "prio", "1")
runTC("class", "change", "dev", t.NIC.ST, "parent", "1:0", "classid", "1:20", "htb", "rate", forward, "prio", "1")

} else {
forward = fmt.Sprintf("%dmbit", int64(math.Round(Trunks.Bandwidth.Forward*Trunks.CurrentACM.Weight)))
retun = fmt.Sprintf("%dmbit", int64(math.Round(Trunks.Bandwidth.Return*Trunks.CurrentACM.Weight)))
runTC("class", "change", "dev", Trunks.NIC.GW, "parent", "1:0", "classid", "1:1", "htb", "rate", retun)
runTC("class", "change", "dev", Trunks.NIC.ST, "parent", "1:0", "classid", "1:1", "htb", "rate", forward)
forward = fmt.Sprintf("%dmbit", int64(math.Round(t.Bandwidth.Forward*t.CurrentACM.Weight)))
retun = fmt.Sprintf("%dmbit", int64(math.Round(t.Bandwidth.Return*t.CurrentACM.Weight)))
runTC("class", "change", "dev", t.NIC.GW, "parent", "1:0", "classid", "1:1", "htb", "rate", retun)
runTC("class", "change", "dev", t.NIC.ST, "parent", "1:0", "classid", "1:1", "htb", "rate", forward)
}
log.Println("Setting the forward link bandwidth at", forward)
log.Println("Setting the return link bandwidth at", retun)

Trunks.ACMCounter = 0
t.ACMCounter = 0
}
Trunks.ACMCounter++
t.ACMCounter++
}
32 changes: 17 additions & 15 deletions runtime/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import (
)

// ParseConf read the yaml file and populate the Config instancce
func ParseConf(file string) error {
func ParseConf(file string) (*TrunksConfig, error) {
var trunksConfig *TrunksConfig
path, err := filepath.Abs(file)
yamlFile, err := ioutil.ReadFile(path)
if err != nil {
return err
return nil, err
}
err = yaml.Unmarshal(yamlFile, &Trunks)
if err != nil {
return err
if err := yaml.Unmarshal(yamlFile, &trunksConfig); err != nil {
return nil, err
}
return nil
return trunksConfig, nil
}

// Interfaces struct
Expand Down Expand Up @@ -47,13 +47,15 @@ type ACM struct {

// TrunksConfig struct
type TrunksConfig struct {
NIC NIC `yaml:"nic"`
Bandwidth Bandwidth `yaml:"bandwidth"`
Delay Delay `yaml:"delay"`
ACMList []*ACM `yaml:"acm"`
QoS bool
Logs string
ACMCounter int
ACMIndex int
CurrentACM *ACM
NIC NIC `yaml:"nic"`
Bandwidth Bandwidth `yaml:"bandwidth"`
Delay Delay `yaml:"delay"`
ACMList []*ACM `yaml:"acm"`
QoS bool
Logs string
KernelVersionCheck bool
ACMEnabled bool
ACMCounter int
ACMIndex int
CurrentACM *ACM
}
46 changes: 25 additions & 21 deletions runtime/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ func Exists(path string) (bool, error) {
}

// CheckInterfaces checks if the interfaces exist
func CheckInterfaces(st string, gw string) error {
func (t *TrunksConfig) CheckInterfaces() error {
path := "/sys/class/net/%s/operstate"
ifST := fmt.Sprintf(path, st)
ifGW := fmt.Sprintf(path, gw)
ifST := fmt.Sprintf(path, t.NIC.ST)
ifGW := fmt.Sprintf(path, t.NIC.GW)
var err1, err2 error
existST, _ := Exists(ifST)
if !existST {
Expand All @@ -44,9 +44,9 @@ func CheckInterfaces(st string, gw string) error {
return nil
}

func FindInterfaces() error {
ip_st := Trunks.NIC.ST
ip_gw := Trunks.NIC.GW
func (t *TrunksConfig) FindInterfaces() error {
ip_st := t.NIC.ST
ip_gw := t.NIC.GW
ifaces, err := net.Interfaces()
if err != nil {
log.Printf("Error reading interfaces: %+v\n", err.Error())
Expand All @@ -61,24 +61,24 @@ func FindInterfaces() error {
for _, a := range addrs {
switch v := a.(type) {
case *net.IPNet:
if v.IP.To4().String() == Trunks.NIC.GW {
Trunks.NIC.GW = i.Name
if v.IP.To4().String() == t.NIC.GW {
t.NIC.GW = i.Name
}
if v.IP.To4().String() == Trunks.NIC.ST {
Trunks.NIC.ST = i.Name
if v.IP.To4().String() == t.NIC.ST {
t.NIC.ST = i.Name
}
}

}
}

var err1, err2 error
if ip_st == Trunks.NIC.ST {
if ip_st == t.NIC.ST {
err1 = errors.New("[L3] Interface for ST not found")
log.Println(err1.Error())
}

if ip_gw == Trunks.NIC.GW {
if ip_gw == t.NIC.GW {
err2 = errors.New("[L3] Interface for GW not found")
log.Println(err2.Error())
}
Expand All @@ -91,17 +91,21 @@ func FindInterfaces() error {
}

// InitTrunks initialize the trunks module
func InitTrunks(file string, qos bool, logs string) error {
err := ParseConf(file)
func InitTrunks(file string, qos bool, logs string, acm bool, disable_kernel_version_check bool) (*TrunksConfig, error) {
t, err := ParseConf(file)
if err != nil {
return err
return nil, err
}
err = CheckInterfaces(Trunks.NIC.ST, Trunks.NIC.GW)
if err != nil {
if err := t.CheckInterfaces(); err != nil {
log.Println("Interfaces configuration by IP")
err = FindInterfaces()
if err := t.FindInterfaces(); err != nil {
return nil, err
}
}
Trunks.QoS = qos
Trunks.Logs = logs
return err

t.QoS = qos
t.Logs = logs
t.ACMEnabled = acm
t.KernelVersionCheck = !disable_kernel_version_check
return t, nil
}
Loading

0 comments on commit 5a973d2

Please sign in to comment.