Skip to content

Commit 78c9095

Browse files
authored
add fwmark (#92)
1 parent 63c75be commit 78c9095

File tree

4 files changed

+40
-24
lines changed

4 files changed

+40
-24
lines changed

defs/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ const (
4242
OptionTelemetryPath = "telemetry-path"
4343
OptionTelemetryShare = "telemetry-share"
4444
OptionTelemetryExtra = "telemetry-extra"
45+
OptionFwmark = "fwmark"
4546
)

main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func main() {
171171
&cli.StringFlag{
172172
Name: defs.OptionCACert,
173173
Usage: "Use the specified CA certificate PEM bundle file instead\n" +
174-
"\tof the system certificate trust store",
174+
"\tof the system certificate trust store",
175175
},
176176
&cli.BoolFlag{
177177
Name: defs.OptionSkipCertVerify,
@@ -218,6 +218,11 @@ func main() {
218218
Usage: "Send a custom message along with the telemetry results.\n" +
219219
"\tImplies --" + defs.OptionShare,
220220
},
221+
&cli.IntFlag{
222+
Name: defs.OptionFwmark,
223+
Usage: "firewall mark to set on socket.",
224+
Value: 0,
225+
},
221226
},
222227
}
223228

speedtest/speedtest.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -161,25 +161,25 @@ func SpeedTest(c *cli.Context) error {
161161
network = "ip"
162162
}
163163

164-
transport := http.DefaultTransport.(*http.Transport).Clone()
165-
166-
if caCertFileName := c.String(defs.OptionCACert); caCertFileName != "" {
167-
caCert, err := ioutil.ReadFile(caCertFileName)
168-
if err != nil {
169-
log.Fatal(err)
170-
}
171-
caCertPool := x509.NewCertPool()
172-
caCertPool.AppendCertsFromPEM(caCert)
173-
174-
transport.TLSClientConfig = &tls.Config{
175-
InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify),
176-
RootCAs: caCertPool,
177-
}
178-
} else {
179-
transport.TLSClientConfig = &tls.Config{
180-
InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify),
181-
}
182-
}
164+
transport := http.DefaultTransport.(*http.Transport).Clone()
165+
166+
if caCertFileName := c.String(defs.OptionCACert); caCertFileName != "" {
167+
caCert, err := ioutil.ReadFile(caCertFileName)
168+
if err != nil {
169+
log.Fatal(err)
170+
}
171+
caCertPool := x509.NewCertPool()
172+
caCertPool.AppendCertsFromPEM(caCert)
173+
174+
transport.TLSClientConfig = &tls.Config{
175+
InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify),
176+
RootCAs: caCertPool,
177+
}
178+
} else {
179+
transport.TLSClientConfig = &tls.Config{
180+
InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify),
181+
}
182+
}
183183

184184
dialer := &net.Dialer{
185185
Timeout: 30 * time.Second,
@@ -195,9 +195,13 @@ func SpeedTest(c *cli.Context) error {
195195
}
196196

197197
// bind to interface if given
198-
if iface := c.String(defs.OptionInterface); iface != "" {
198+
// bind to interface if given
199+
iface := c.String(defs.OptionInterface)
200+
fwmark := c.Int(defs.OptionFwmark)
201+
202+
if iface != "" || fwmark > 0 {
199203
var err error
200-
dialer, err = newDialerInterfaceBound(iface)
204+
dialer, err = newDialerInterfaceOrFwmarkBound(iface, fwmark)
201205
if err != nil {
202206
return err
203207
}

speedtest/util_linux.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ import (
88
"golang.org/x/sys/unix"
99
)
1010

11-
func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) {
11+
func newDialerInterfaceOrFwmarkBound(iface string, fwmark int) (dialer *net.Dialer, err error) {
1212
// In linux there is the socket option SO_BINDTODEVICE.
1313
// Therefore we can really bind the socket to the device instead of binding to the address that
1414
// would be affected by the default routes.
1515
control := func(network, address string, c syscall.RawConn) error {
1616
var errSock error
1717
err := c.Control((func(fd uintptr) {
18-
errSock = unix.BindToDevice(int(fd), iface)
18+
if iface != "" {
19+
errSock = unix.BindToDevice(int(fd), iface)
20+
}
21+
22+
if fwmark > 0 {
23+
errSock = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, fwmark)
24+
}
1925
}))
2026
if err != nil {
2127
return err

0 commit comments

Comments
 (0)