-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdocker-comcast.patch
171 lines (163 loc) · 6.29 KB
/
docker-comcast.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
diff --git a/comcast.go b/comcast.go
index a300611..ddaee91 100644
--- a/comcast.go
+++ b/comcast.go
@@ -1,13 +1,16 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"net"
"os"
+ "os/exec"
"strconv"
"strings"
+ "github.com/samalba/dockerclient"
"github.com/tylertreat/comcast/throttler"
)
@@ -16,6 +19,7 @@ const version = "1.0.0"
func main() {
// TODO: Add support for other options like packet reordering, duplication, etc.
var (
+ cont = flag.String("cont", "", "Container ID or name to get virtual interface of")
device = flag.String("device", "", "Interface (device) to use (defaults to eth0 where applicable)")
stop = flag.Bool("stop", false, "Stop packet controls")
latency = flag.Int("latency", -1, "Latency to add in ms")
@@ -38,6 +42,48 @@ func main() {
targetIPv4, targetIPv6 := parseAddrs(*targetaddr)
+ // Probably don't want to apply to eth0 by default when in a container
+ if *cont == "" && *device == "" {
+ fmt.Println("Must specify container or device")
+ os.Exit(1)
+ }
+ if *cont != "" {
+ if *device != "" {
+ fmt.Println("Cannot specify container and device")
+ os.Exit(1)
+ }
+ endpoint := "unix:///var/run/docker.sock"
+ docker, err := dockerclient.NewDockerClient(endpoint, nil)
+ if err != nil {
+ fmt.Println("Couldn't connect to docker socket:", err)
+ os.Exit(1)
+ }
+ container, err := docker.InspectContainer(*cont)
+ if err != nil {
+ fmt.Println("Couldn't inspect container:", err)
+ os.Exit(1)
+ }
+ pid := container.State.Pid
+ if pid < 2 {
+ fmt.Println("Couldn't find process id for container")
+ os.Exit(1)
+ }
+ cmd := exec.Command("findveth.sh", strconv.Itoa(pid))
+ var outbuf bytes.Buffer
+ var errbuf bytes.Buffer
+ cmd.Stdout = &outbuf
+ cmd.Stderr = &errbuf
+ err = cmd.Run()
+ outstr := outbuf.String()
+ errstr := errbuf.String()
+ if err != nil {
+ fmt.Println("Failed to find interface:", err, outstr, errstr)
+ os.Exit(1)
+ }
+ *device = strings.TrimSpace(outstr)
+ fmt.Printf("Found interface %s for container '%s'\n", *device, *cont)
+ }
+
throttler.Run(&throttler.Config{
Device: *device,
Stop: *stop,
diff --git a/throttler/tc.go b/throttler/tc.go
index a295968..902e818 100644
--- a/throttler/tc.go
+++ b/throttler/tc.go
@@ -131,6 +131,15 @@ func addNetemRule(cfg *Config, c commander) error {
func addIptablesRules(cfg *Config, c commander) error {
var err error
+ if len(cfg.TargetIps) == 0 && len(cfg.TargetIps6) == 0 {
+ if err == nil {
+ err = addIptablesRulesForAddrs(cfg, c, ip4Tables, cfg.TargetIps)
+ }
+ if err == nil {
+ err = addIptablesRulesForAddrs(cfg, c, ip6Tables, cfg.TargetIps6)
+ }
+ return err
+ }
if err == nil && len(cfg.TargetIps) > 0 {
err = addIptablesRulesForAddrs(cfg, c, ip4Tables, cfg.TargetIps)
}
diff --git a/throttler/tc_test.go b/throttler/tc_test.go
index 122e9fe..b31fd0a 100644
--- a/throttler/tc_test.go
+++ b/throttler/tc_test.go
@@ -50,7 +50,7 @@ func (r *cmdRecorder) verifyCommands(t *testing.T, expected []string) {
for i, cmd := range expected {
if actual := r.commands[i]; actual != cmd {
- t.Fatalf("Expected to see command `%s`, got `%s`", i, cmd, actual)
+ t.Fatalf("Expected to see command `%s`, got `%s`", cmd, actual)
}
}
}
@@ -76,14 +76,33 @@ func TestTcPacketLossSetup(t *testing.T) {
cfg.PacketLoss = 0.2
th.setup(&cfg)
r.verifyCommands(t, []string{
- "sudo tc qdisc add dev eth1 handle 10: root htb",
+ "sudo tc qdisc add dev eth1 handle 10: root htb default 1",
"sudo tc class add dev eth1 parent 10: classid 10:1 htb rate 20000kbit",
- "sudo tc class add dev eth1 parent 10:1 classid 10:10 htb rate 20000kbit",
+ "sudo tc class add dev eth1 parent 10: classid 10:10 htb rate 1000000kbit",
"sudo tc qdisc add dev eth1 parent 10:10 handle 100: netem loss 0.20%",
"sudo iptables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10 -p tcp --dport 80 -d 10.10.10.10",
})
}
+func TestTcWildcardIps(t *testing.T) {
+ r := newCmdRecorder()
+ th := &tcThrottler{r}
+ cfg := defaultTestConfig
+ cfg.TargetIps = []string{}
+ cfg.TargetPorts = []string{}
+ cfg.TargetProtos = []string{}
+ cfg.PacketLoss = -1
+ th.setup(&cfg)
+ r.verifyCommands(t, []string{
+ "sudo tc qdisc add dev eth0 handle 10: root htb default 1",
+ "sudo tc class add dev eth0 parent 10: classid 10:1 htb rate 20000kbit",
+ "sudo tc class add dev eth0 parent 10: classid 10:10 htb rate 1000000kbit",
+ "sudo tc qdisc add dev eth0 parent 10:10 handle 100: netem",
+ "sudo iptables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10",
+ "sudo ip6tables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10",
+ })
+}
+
func TestTcMultiplePortsAndIps(t *testing.T) {
r := newCmdRecorder()
th := &tcThrottler{r}
@@ -93,9 +112,9 @@ func TestTcMultiplePortsAndIps(t *testing.T) {
cfg.TargetProtos = []string{"tcp", "udp"}
th.setup(&cfg)
r.verifyCommands(t, []string{
- "sudo tc qdisc add dev eth0 handle 10: root htb",
+ "sudo tc qdisc add dev eth0 handle 10: root htb default 1",
"sudo tc class add dev eth0 parent 10: classid 10:1 htb rate 20000kbit",
- "sudo tc class add dev eth0 parent 10:1 classid 10:10 htb rate 20000kbit",
+ "sudo tc class add dev eth0 parent 10: classid 10:10 htb rate 1000000kbit",
"sudo tc qdisc add dev eth0 parent 10:10 handle 100: netem loss 0.10%",
"sudo iptables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10 -p tcp --match multiport --dports 80,8080 -d 1.1.1.1",
"sudo iptables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10 -p udp --match multiport --dports 80,8080 -d 1.1.1.1",
@@ -113,9 +132,9 @@ func TestTcMixedIPv6Setup(t *testing.T) {
cfg.TargetIps6 = []string{"2001:db8::1"}
th.setup(&cfg)
r.verifyCommands(t, []string{
- "sudo tc qdisc add dev eth1 handle 10: root htb",
+ "sudo tc qdisc add dev eth1 handle 10: root htb default 1",
"sudo tc class add dev eth1 parent 10: classid 10:1 htb rate 20000kbit",
- "sudo tc class add dev eth1 parent 10:1 classid 10:10 htb rate 20000kbit",
+ "sudo tc class add dev eth1 parent 10: classid 10:10 htb rate 1000000kbit",
"sudo tc qdisc add dev eth1 parent 10:10 handle 100: netem loss 0.20%",
"sudo iptables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10 -p tcp --dport 80 -d 10.10.10.10",
"sudo ip6tables -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10 -p tcp --dport 80 -d 2001:db8::1",