net/netns: unindent, refactor to remove some redunant code
Also:
* always error on Control failing. That's very unexpected.
* pull out sockopt funcs into their own funcs for easier future testing
@@ -110,25 +110,32 @@ func control(network, address string, c syscall.RawConn) error {
return nil
}
- if ipRuleAvailable() {
- var controlErr error
+ var sockErr error
err := c.Control(func(fd uintptr) {
- controlErr = unix.SetsockoptInt(int(fd),
- unix.SOL_SOCKET, unix.SO_MARK,
- tailscaleBypassMark)
+ if ipRuleAvailable() {
+ sockErr = setBypassMark(fd)
+ } else {
+ sockErr = bindToDevice(fd)
+ }
})
- if (err != nil || controlErr != nil) && ignoreErrors() {
+ if err != nil {
+ return fmt.Errorf("RawConn.Control on %T: %w", c, err)
+ }
+ if sockErr != nil && ignoreErrors() {
+ // TODO(bradfitz): maybe log once? probably too spammy for e.g. CLI tools like tailscale netcheck.
return nil
}
- if err != nil {
- return fmt.Errorf("setting socket mark1: %w", err)
+ return sockErr
}
- if controlErr != nil {
- return fmt.Errorf("setting socket mark2: %w", controlErr)
+
+func setBypassMark(fd uintptr) error {
+ if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, tailscaleBypassMark); err != nil {
+ return fmt.Errorf("setting SO_MARK bypass: %w", err)
}
- } else {
- var controlErr error
- err := c.Control(func(fd uintptr) {
+ return nil
+}
+
+func bindToDevice(fd uintptr) error {
ifc, err := defaultRouteInterface()
if err != nil {
// Make sure we bind to *some* interface,
@@ -137,18 +144,8 @@ func control(network, address string, c syscall.RawConn) error {
// a default route anyway, it doesn't matter.
ifc = "lo"
}
- controlErr = unix.SetsockoptString(int(fd),
- unix.SOL_SOCKET, unix.SO_BINDTODEVICE, ifc)
- })
- if (err != nil || controlErr != nil) && ignoreErrors() {
- return nil
- }
- if err != nil {
- return fmt.Errorf("setting SO_BINDTODEVICE 1: %w", err)
- }
- if controlErr != nil {
- return fmt.Errorf("setting SO_BINDTODEVICE 2: %w", controlErr)
- }
+ if err := unix.SetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_BINDTODEVICE, ifc); err != nil {
+ return fmt.Errorf("setting SO_BINDTODEVICE: %w", err)
}
return nil
}
