mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 03:25:35 +00:00
1642dfdb07
IPv4 and IPv6 both work remotely, but IPv6 doesn't yet work from the machine itself due to routing mysteries. Untested yet on iOS, but previous prototype worked on iOS, so should work the same. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build darwin,redo ios,redo
|
|
|
|
package ipnlocal
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
"inet.af/netaddr"
|
|
"tailscale.com/net/interfaces"
|
|
)
|
|
|
|
func init() {
|
|
initListenConfig = initListenConfigNetworkExtension
|
|
}
|
|
|
|
// initListenConfigNetworkExtension configures nc for listening on IP
|
|
// through the iOS/macOS Network/System Extension (Packet Tunnel
|
|
// Provider) sandbox.
|
|
func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netaddr.IP, st *interfaces.State, tunIfName string) error {
|
|
tunIf, ok := st.Interface[tunIfName]
|
|
if !ok {
|
|
return fmt.Errorf("no interface with name %q", tunIfName)
|
|
}
|
|
nc.Control = func(network, address string, c syscall.RawConn) error {
|
|
var sockErr error
|
|
err := c.Control(func(fd uintptr) {
|
|
|
|
v6 := strings.Contains(address, "]:") || strings.HasSuffix(network, "6") // hacky test for v6
|
|
proto := unix.IPPROTO_IP
|
|
opt := unix.IP_BOUND_IF
|
|
if v6 {
|
|
proto = unix.IPPROTO_IPV6
|
|
opt = unix.IPV6_BOUND_IF
|
|
}
|
|
|
|
sockErr = unix.SetsockoptInt(int(fd), proto, opt, tunIf.Index)
|
|
log.Printf("peerapi: bind(%q, %q) on index %v = %v", network, address, tunIf.Index, sockErr)
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return sockErr
|
|
}
|
|
return nil
|
|
}
|