mirror of
https://github.com/ehang-io/nps.git
synced 2025-07-02 04:00:42 +00:00
change md
This commit is contained in:
parent
6dbe6cb5dd
commit
e5b3db0c19
184
lib/mux/tc.go
184
lib/mux/tc.go
@ -1 +1,185 @@
|
||||
package mux
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Eth struct {
|
||||
EthName string
|
||||
EthAddr string
|
||||
}
|
||||
|
||||
type TrafficControl struct {
|
||||
Eth *Eth
|
||||
}
|
||||
|
||||
func Ips() (map[string]string, error) {
|
||||
|
||||
ips := make(map[string]string)
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, i := range interfaces {
|
||||
byName, err := net.InterfaceByName(i.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !strings.Contains(byName.Name, "Loopback") && !strings.Contains(byName.Name, "isatap") {
|
||||
addresses, _ := byName.Addrs()
|
||||
for _, v := range addresses {
|
||||
ips[byName.Name] = v.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
// get ip and Eth information by Eth name
|
||||
func GetIpAddrByName(EthName string) (Eth *Eth, err error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, i := range interfaces {
|
||||
byName, err := net.InterfaceByName(i.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if byName.Name == EthName || EthName == "" {
|
||||
// except lo
|
||||
if !strings.Contains(byName.Name, "Loopback") && !strings.Contains(byName.Name, "isatap") {
|
||||
addresses, _ := byName.Addrs()
|
||||
for _, v := range addresses {
|
||||
ipMask := strings.Split(v.String(), "/")
|
||||
if len(ipMask) == 2 {
|
||||
Eth.EthAddr = ipMask[0]
|
||||
Eth.EthName = byName.Name
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = errors.New("not found interface")
|
||||
return
|
||||
}
|
||||
|
||||
type tcFunc func() error
|
||||
|
||||
func getArrayExhaustivity(arr []tcFunc) (result [][]tcFunc) {
|
||||
var l = int(math.Pow(float64(2), float64(len(arr))) - 1)
|
||||
var t []tcFunc
|
||||
for i := 1; i <= l; i++ {
|
||||
s := i
|
||||
t = []tcFunc{}
|
||||
for k := 0; s > 0; k++ {
|
||||
if s&1 == 1 {
|
||||
t = append(t, arr[k])
|
||||
}
|
||||
s >>= 1
|
||||
}
|
||||
result = append(result, t)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NewTrafficControl(EthName string) (*TrafficControl, error) {
|
||||
Eth, err := GetIpAddrByName(EthName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := new(TrafficControl)
|
||||
t.Eth = Eth
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// test the network randomly
|
||||
func (tc *TrafficControl) RunNetRangeTest(f func()) error {
|
||||
funcs := tc.getTestVariable()
|
||||
groups := getArrayExhaustivity(funcs)
|
||||
for _, v := range groups {
|
||||
// execute bandwidth control
|
||||
if err := tc.bandwidth("1mbit"); err != nil {
|
||||
return err
|
||||
}
|
||||
// execute random strategy
|
||||
for _, vv := range v {
|
||||
err := vv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// execute test func
|
||||
f()
|
||||
// clear strategy
|
||||
if err := tc.del(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// create test variables
|
||||
func (tc *TrafficControl) getTestVariable() []tcFunc {
|
||||
return []tcFunc{
|
||||
func() error { return tc.delay("add", "100ms", "10ms", "30%") },
|
||||
func() error { return tc.loss("add", "1%", "30%") },
|
||||
func() error { return tc.duplicate("add", "1%") },
|
||||
func() error { return tc.corrupt("add", "0.2%") },
|
||||
func() error { return tc.reorder("change", "10ms", "25%", "50%") },
|
||||
}
|
||||
}
|
||||
|
||||
// this command sets the transmission of the network card to delayVal. At the same time,
|
||||
// about waveRatio of the packets will be delayed by ± wave.
|
||||
func (tc *TrafficControl) delay(opt, delayVal, wave, waveRatio string) error {
|
||||
return runCmd(exec.Command("tc", "qdisc", opt, "dev", tc.Eth.EthName, "root", "netem", "delay", delayVal, wave, waveRatio))
|
||||
}
|
||||
|
||||
// this command sets the transmission of the network card to randomly drop lossRatio of packets with a success rate of lossSuccessRatio.
|
||||
func (tc *TrafficControl) loss(opt, lossRatio, lossSuccessRatio string) error {
|
||||
return runCmd(exec.Command("tc", "qdisc", opt, "dev", tc.Eth.EthName, "root", "netem", "loss", lossRatio, lossSuccessRatio))
|
||||
}
|
||||
|
||||
// this command sets the transmission of the network card to randomly generate repeatRatio duplicate packets
|
||||
func (tc *TrafficControl) duplicate(opt, duplicateRatio string) error {
|
||||
return runCmd(exec.Command("tc", "qdisc", opt, "dev", tc.Eth.EthName, "root", "netem", "duplicate", duplicateRatio))
|
||||
}
|
||||
|
||||
// this command sets the transmission of the network card to randomly generate corruptRatio corrupted packets.
|
||||
// the kernel version must be above 2.6.16
|
||||
func (tc *TrafficControl) corrupt(opt, corruptRatio string) error {
|
||||
return runCmd(exec.Command("tc", "qdisc", opt, "dev", tc.Eth.EthName, "root", "netem", "corrupt", corruptRatio))
|
||||
}
|
||||
|
||||
// this command sets the transmission of the network card to: reorderRatio of the packets (reorderRelationRatio related)
|
||||
// will be sent immediately, and the other is delayed by delayVal
|
||||
func (tc *TrafficControl) reorder(opt, delayVal, reorderRatio, reorderRelationRatio string) error {
|
||||
return runCmd(exec.Command("tc", "qdisc", opt, "dev", tc.Eth.EthName, "root", "netem", "delay", delayVal, "reorder", reorderRatio, reorderRelationRatio))
|
||||
}
|
||||
|
||||
// remove all tc setting
|
||||
func (tc *TrafficControl) del() error {
|
||||
return runCmd(exec.Command("tc", "qdisc", "del", "dev", tc.Eth.EthName, "root"))
|
||||
}
|
||||
|
||||
// remove all tc setting
|
||||
func (tc *TrafficControl) bandwidth(bw string) error {
|
||||
runCmd(exec.Command("tc", "qdisc", "add", "dev", tc.Eth.EthName, "root", "handle", "2:", "htb", "default", "30"))
|
||||
return runCmd(exec.Command("tc", "qdisc", "add", "dev", tc.Eth.EthName, "parent", "2:", "classid", "2:30", "htb", "rate", bw))
|
||||
}
|
||||
|
||||
func runCmd(cmd *exec.Cmd) error {
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user