aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-06-17 22:54:59 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-06-18 11:39:38 +0200
commit96e5d80a3e8c2b874b321bc5918971f8ea63d2c6 (patch)
tree71ca822435f2f0941b9969a9583cd1d07320f6a3
parentglobal: go fmt for 1.17 build tags (diff)
downloadwireguard-windows-96e5d80a3e8c2b874b321bc5918971f8ea63d2c6.tar.xz
wireguard-windows-96e5d80a3e8c2b874b321bc5918971f8ea63d2c6.zip
tunnel: support turning off automatic routing table
This supports the familiar "Table = off" syntax as on Linux, and then interprets other valid values as simply "on". Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--conf/config.go1
-rw-r--r--conf/parser.go17
-rw-r--r--conf/writer.go3
-rw-r--r--tunnel/addressconfig.go10
-rw-r--r--ui/confview.go8
-rw-r--r--ui/editdialog.go2
-rw-r--r--ui/syntax/highlighter.go10
-rw-r--r--ui/syntax/syntaxedit.go14
8 files changed, 57 insertions, 8 deletions
diff --git a/conf/config.go b/conf/config.go
index 0a6c6abf..a6266851 100644
--- a/conf/config.go
+++ b/conf/config.go
@@ -53,6 +53,7 @@ type Interface struct {
PostUp string
PreDown string
PostDown string
+ TableOff bool
}
type Peer struct {
diff --git a/conf/parser.go b/conf/parser.go
index bd08ee6c..9c1295bf 100644
--- a/conf/parser.go
+++ b/conf/parser.go
@@ -137,6 +137,16 @@ func parsePersistentKeepalive(s string) (uint16, error) {
return uint16(m), nil
}
+func parseTableOff(s string) (bool, error) {
+ if s == "off" {
+ return true, nil
+ } else if s == "auto" || s == "main" {
+ return false, nil
+ }
+ _, err := strconv.ParseUint(s, 10, 32)
+ return false, err
+}
+
func parseKeyBase64(s string) (*Key, error) {
k, err := base64.StdEncoding.DecodeString(s)
if err != nil {
@@ -292,6 +302,12 @@ func FromWgQuick(s string, name string) (*Config, error) {
conf.Interface.PreDown = val
case "postdown":
conf.Interface.PostDown = val
+ case "table":
+ tableOff, err := parseTableOff(val)
+ if err != nil {
+ return nil, err
+ }
+ conf.Interface.TableOff = tableOff
default:
return nil, &ParseError{l18n.Sprintf("Invalid key for [Interface] section"), key}
}
@@ -382,6 +398,7 @@ func FromUAPI(reader io.Reader, existingConfig *Config) (*Config, error) {
PostUp: existingConfig.Interface.PostUp,
PreDown: existingConfig.Interface.PreDown,
PostDown: existingConfig.Interface.PostDown,
+ TableOff: existingConfig.Interface.TableOff,
},
}
var peer *Peer
diff --git a/conf/writer.go b/conf/writer.go
index c786ec10..ddf54aa5 100644
--- a/conf/writer.go
+++ b/conf/writer.go
@@ -53,6 +53,9 @@ func (conf *Config) ToWgQuick() string {
if len(conf.Interface.PostDown) > 0 {
output.WriteString(fmt.Sprintf("PostDown = %s\n", conf.Interface.PostDown))
}
+ if conf.Interface.TableOff {
+ output.WriteString("Table = off\n")
+ }
for _, peer := range conf.Peers {
output.WriteString("\n[Peer]\n")
diff --git a/tunnel/addressconfig.go b/tunnel/addressconfig.go
index 44bfd8ae..0dec95d0 100644
--- a/tunnel/addressconfig.go
+++ b/tunnel/addressconfig.go
@@ -138,9 +138,11 @@ func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, tun *t
deduplicatedRoutes = append(deduplicatedRoutes, &routes[i])
}
- err = luid.SetRoutesForFamily(family, deduplicatedRoutes)
- if err != nil {
- return err
+ if !conf.Interface.TableOff {
+ err = luid.SetRoutesForFamily(family, deduplicatedRoutes)
+ if err != nil {
+ return err
+ }
}
ipif, err := luid.IPInterface(family)
@@ -174,7 +176,7 @@ func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, tun *t
func enableFirewall(conf *conf.Config, tun *tun.NativeTun) error {
doNotRestrict := true
- if len(conf.Peers) == 1 {
+ if len(conf.Peers) == 1 && !conf.Interface.TableOff {
nextallowedip:
for _, allowedip := range conf.Peers[0].AllowedIPs {
if allowedip.Cidr == 0 {
diff --git a/ui/confview.go b/ui/confview.go
index cc3bcad9..3d16f38f 100644
--- a/ui/confview.go
+++ b/ui/confview.go
@@ -51,6 +51,7 @@ type interfaceView struct {
addresses *labelTextLine
dns *labelTextLine
scripts *labelTextLine
+ table *labelTextLine
toggleActive *toggleActiveLine
lines []widgetsLine
}
@@ -307,6 +308,7 @@ func newInterfaceView(parent walk.Container) (*interfaceView, error) {
{l18n.Sprintf("Addresses:"), &iv.addresses},
{l18n.Sprintf("DNS servers:"), &iv.dns},
{l18n.Sprintf("Scripts:"), &iv.scripts},
+ {l18n.Sprintf("Table:"), &iv.table},
}
if iv.lines, err = createLabelTextLines(items, parent, &disposables); err != nil {
return nil, err
@@ -427,6 +429,12 @@ func (iv *interfaceView) apply(c *conf.Interface) {
} else {
iv.scripts.hide()
}
+
+ if c.TableOff {
+ iv.table.show(l18n.Sprintf("off"))
+ } else {
+ iv.table.hide()
+ }
}
func (pv *peerView) widgetsLines() []widgetsLine {
diff --git a/ui/editdialog.go b/ui/editdialog.go
index 71b71150..3b1521ff 100644
--- a/ui/editdialog.go
+++ b/ui/editdialog.go
@@ -129,7 +129,7 @@ func newEditDialog(owner walk.Form, tunnel *manager.Tunnel) (*EditDialog, error)
return nil, err
}
dlg.blockUntunneledTrafficCB.SetText(l18n.Sprintf("&Block untunneled traffic (kill-switch)"))
- dlg.blockUntunneledTrafficCB.SetToolTipText(l18n.Sprintf("When a configuration has exactly one peer, and that peer has an allowed IPs containing at least one of 0.0.0.0/0 or ::/0, then the tunnel service engages a firewall ruleset to block all traffic that is neither to nor from the tunnel interface or is to the wrong DNS server, with special exceptions for DHCP and NDP."))
+ dlg.blockUntunneledTrafficCB.SetToolTipText(l18n.Sprintf("When a configuration has exactly one peer, and that peer has an allowed IPs containing at least one of 0.0.0.0/0 or ::/0, and the interface does not have table off, then the tunnel service engages a firewall ruleset to block all traffic that is neither to nor from the tunnel interface or is to the wrong DNS server, with special exceptions for DHCP and NDP."))
dlg.blockUntunneledTrafficCB.SetVisible(false)
dlg.blockUntunneledTrafficCB.CheckedChanged().Attach(dlg.onBlockUntunneledTrafficCBCheckedChanged)
diff --git a/ui/syntax/highlighter.go b/ui/syntax/highlighter.go
index d49cab32..a531854b 100644
--- a/ui/syntax/highlighter.go
+++ b/ui/syntax/highlighter.go
@@ -26,6 +26,7 @@ const (
highlightKeepalive
highlightComment
highlightDelimiter
+ highlightTable
highlightCmd
highlightError
)
@@ -256,6 +257,10 @@ func (s stringSpan) isValidMTU() bool {
return s.isValidUint(false, 576, 65535)
}
+func (s stringSpan) isValidTable() bool {
+ return s.isSame("off") || s.isSame("auto") || s.isSame("main") || s.isValidUint(false, 0, (1<<32)-1)
+}
+
func (s stringSpan) isValidPersistentKeepAlive() bool {
if s.isSame("off") {
return true
@@ -360,6 +365,7 @@ const (
fieldAddress
fieldDNS
fieldMTU
+ fieldTable
fieldPreUp
fieldPostUp
fieldPreDown
@@ -395,6 +401,8 @@ func (s stringSpan) field() field {
return fieldDNS
case s.isCaselessSame("MTU"):
return fieldMTU
+ case s.isCaselessSame("Table"):
+ return fieldTable
case s.isCaselessSame("PublicKey"):
return fieldPublicKey
case s.isCaselessSame("PresharedKey"):
@@ -508,6 +516,8 @@ func (hsa *highlightSpanArray) highlightValue(parent stringSpan, s stringSpan, s
hsa.append(parent.s, s, validateHighlight(s.isValidKey(), highlightPresharedKey))
case fieldMTU:
hsa.append(parent.s, s, validateHighlight(s.isValidMTU(), highlightMTU))
+ case fieldTable:
+ hsa.append(parent.s, s, validateHighlight(s.isValidTable(), highlightTable))
case fieldPreUp, fieldPostUp, fieldPreDown, fieldPostDown:
hsa.append(parent.s, s, validateHighlight(s.isValidPrePostUpDown(), highlightCmd))
case fieldListenPort:
diff --git a/ui/syntax/syntaxedit.go b/ui/syntax/syntaxedit.go
index 26cd533f..42f6e7b7 100644
--- a/ui/syntax/syntaxedit.go
+++ b/ui/syntax/syntaxedit.go
@@ -100,6 +100,7 @@ var stylemap = map[highlight]spanStyle{
highlightHost: spanStyle{color: win.RGB(0x0E, 0x0E, 0xFF)},
highlightPort: spanStyle{color: win.RGB(0x81, 0x5F, 0x03)},
highlightMTU: spanStyle{color: win.RGB(0x1C, 0x00, 0xCF)},
+ highlightTable: spanStyle{color: win.RGB(0x1C, 0x00, 0xCF)},
highlightKeepalive: spanStyle{color: win.RGB(0x1C, 0x00, 0xCF)},
highlightComment: spanStyle{color: win.RGB(0x53, 0x65, 0x79), effects: win.CFE_ITALIC},
highlightDelimiter: spanStyle{color: win.RGB(0x00, 0x00, 0x00)},
@@ -110,6 +111,8 @@ var stylemap = map[highlight]spanStyle{
func (se *SyntaxEdit) evaluateUntunneledBlocking(cfg string, spans []highlightSpan) {
state := InevaluableBlockingUntunneledTraffic
var onAllowedIPs,
+ onTable,
+ tableOff,
seenPeer,
seen00v6,
seen00v4,
@@ -132,10 +135,13 @@ func (se *SyntaxEdit) evaluateUntunneledBlocking(cfg string, spans []highlightSp
} else {
goto done
}
- break
case highlightField:
onAllowedIPs = strings.EqualFold(cfg[span.s:span.s+span.len], "AllowedIPs")
- break
+ onTable = strings.EqualFold(cfg[span.s:span.s+span.len], "Table")
+ case highlightTable:
+ if onTable {
+ tableOff = cfg[span.s:span.s+span.len] == "off"
+ }
case highlightIP:
if !onAllowedIPs || !seenPeer {
break
@@ -166,9 +172,11 @@ func (se *SyntaxEdit) evaluateUntunneledBlocking(cfg string, spans []highlightSp
seen80001v6 = true
}
}
- break
}
}
+ if tableOff {
+ return
+ }
if seen00v4 || seen00v6 {
state = BlockingUntunneledTraffic