Merge branch 'master' of ssh://git.zx2c4.com/wireguard-go
This commit is contained in:
		
						commit
						edbce6b400
					
				@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "errors"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								conn.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								conn.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,10 @@
 | 
			
		||||
// +build !linux
 | 
			
		||||
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,6 @@
 | 
			
		||||
/* Copyright 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This implements userspace semantics of "sticky sockets", modeled after
 | 
			
		||||
 * WireGuard's kernelspace implementation. This is more or less a straight port
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Daemonize() error {
 | 
			
		||||
	return errors.New("Not implemented on OSX")
 | 
			
		||||
}
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* Daemonizes the process on linux
 | 
			
		||||
 *
 | 
			
		||||
 * This is done by spawning and releasing a copy with the --foreground flag
 | 
			
		||||
 */
 | 
			
		||||
func Daemonize(attr *os.ProcAttr) error {
 | 
			
		||||
	// I would like to use os.Executable,
 | 
			
		||||
	// however this means dropping support for Go <1.8
 | 
			
		||||
	path, err := exec.LookPath(os.Args[0])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	argv := []string{os.Args[0], "--foreground"}
 | 
			
		||||
	argv = append(argv, os.Args[1:]...)
 | 
			
		||||
	process, err := os.StartProcess(
 | 
			
		||||
		path,
 | 
			
		||||
		argv,
 | 
			
		||||
		attr,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	process.Release()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@ -1,34 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* Daemonizes the process on windows
 | 
			
		||||
 *
 | 
			
		||||
 * This is done by spawning and releasing a copy with the --foreground flag
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
func Daemonize() error {
 | 
			
		||||
	argv := []string{os.Args[0], "--foreground"}
 | 
			
		||||
	argv = append(argv, os.Args[1:]...)
 | 
			
		||||
	attr := &os.ProcAttr{
 | 
			
		||||
		Dir: ".",
 | 
			
		||||
		Env: os.Environ(),
 | 
			
		||||
		Files: []*os.File{
 | 
			
		||||
			os.Stdin,
 | 
			
		||||
			nil,
 | 
			
		||||
			nil,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	process, err := os.StartProcess(
 | 
			
		||||
		argv[0],
 | 
			
		||||
		argv,
 | 
			
		||||
		attr,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	process.Release()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
/* Create two device instances and simulate full WireGuard interaction
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								index.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								index.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								ip.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								ip.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										97
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								main.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@ -14,8 +19,9 @@ const (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ENV_WG_TUN_FD  = "WG_TUN_FD"
 | 
			
		||||
	ENV_WG_UAPI_FD = "WG_UAPI_FD"
 | 
			
		||||
	ENV_WG_TUN_FD             = "WG_TUN_FD"
 | 
			
		||||
	ENV_WG_UAPI_FD            = "WG_UAPI_FD"
 | 
			
		||||
	ENV_WG_PROCESS_FOREGROUND = "WG_PROCESS_FOREGROUND"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func printUsage() {
 | 
			
		||||
@ -23,7 +29,45 @@ func printUsage() {
 | 
			
		||||
	fmt.Printf("%s [-f/--foreground] INTERFACE-NAME\n", os.Args[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func warning() {
 | 
			
		||||
	shouldQuit := false
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W                                                     G")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W   This is alpha software. It will very likely not   G")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W   do what it is supposed to do, and things may go   G")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W   horribly wrong. You have been warned. Proceed     G")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W   at your own risk.                                 G")
 | 
			
		||||
	if runtime.GOOS == "linux" {
 | 
			
		||||
		shouldQuit = os.Getenv("WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD") != "1"
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W                                                     G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   Furthermore, you are running this software on a   G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   Linux kernel, which is probably unnecessary and   G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   foolish. This is because the Linux kernel has     G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   built-in first class support for WireGuard, and   G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   this support is much more refined than this       G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   program. For more information on installing the   G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W   kernel module, please visit:                      G")
 | 
			
		||||
		fmt.Fprintln(os.Stderr, "W           https://www.wireguard.com/install         G")
 | 
			
		||||
		if shouldQuit {
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "W                                                     G")
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "W   If you still want to use this program, against    G")
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "W   the sage advice here, please first export this    G")
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "W   environment variable:                             G")
 | 
			
		||||
			fmt.Fprintln(os.Stderr, "W   WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1    G")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "W                                                     G")
 | 
			
		||||
	fmt.Fprintln(os.Stderr, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING")
 | 
			
		||||
 | 
			
		||||
	if shouldQuit {
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	warning()
 | 
			
		||||
 | 
			
		||||
	// parse arguments
 | 
			
		||||
 | 
			
		||||
@ -53,6 +97,10 @@ func main() {
 | 
			
		||||
		interfaceName = os.Args[1]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !foreground {
 | 
			
		||||
		foreground = os.Getenv(ENV_WG_PROCESS_FOREGROUND) == "1"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get log level (default: info)
 | 
			
		||||
 | 
			
		||||
	logLevel := func() int {
 | 
			
		||||
@ -67,13 +115,6 @@ func main() {
 | 
			
		||||
		return LogLevelInfo
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	logger := NewLogger(
 | 
			
		||||
		logLevel,
 | 
			
		||||
		fmt.Sprintf("(%s) ", interfaceName),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	logger.Debug.Println("Debug log enabled")
 | 
			
		||||
 | 
			
		||||
	// open TUN device (or use supplied fd)
 | 
			
		||||
 | 
			
		||||
	tun, err := func() (TUNDevice, error) {
 | 
			
		||||
@ -93,6 +134,21 @@ func main() {
 | 
			
		||||
		return CreateTUNFromFile(file)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		realInterfaceName, err2 := tun.Name()
 | 
			
		||||
		if err2 == nil {
 | 
			
		||||
			interfaceName = realInterfaceName
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logger := NewLogger(
 | 
			
		||||
		logLevel,
 | 
			
		||||
		fmt.Sprintf("(%s) ", interfaceName),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	logger.Debug.Println("Debug log enabled")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Println("Failed to create TUN device:", err)
 | 
			
		||||
		os.Exit(ExitSetupFailed)
 | 
			
		||||
@ -127,6 +183,7 @@ func main() {
 | 
			
		||||
		env := os.Environ()
 | 
			
		||||
		env = append(env, fmt.Sprintf("%s=3", ENV_WG_TUN_FD))
 | 
			
		||||
		env = append(env, fmt.Sprintf("%s=4", ENV_WG_UAPI_FD))
 | 
			
		||||
		env = append(env, fmt.Sprintf("%s=1", ENV_WG_PROCESS_FOREGROUND))
 | 
			
		||||
		attr := &os.ProcAttr{
 | 
			
		||||
			Files: []*os.File{
 | 
			
		||||
				nil, // stdin
 | 
			
		||||
@ -138,18 +195,26 @@ func main() {
 | 
			
		||||
			Dir: ".",
 | 
			
		||||
			Env: env,
 | 
			
		||||
		}
 | 
			
		||||
		err = Daemonize(attr)
 | 
			
		||||
 | 
			
		||||
		path, err := os.Executable()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logger.Error.Println("Failed to determine executable:", err)
 | 
			
		||||
			os.Exit(ExitSetupFailed)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		process, err := os.StartProcess(
 | 
			
		||||
			path,
 | 
			
		||||
			os.Args,
 | 
			
		||||
			attr,
 | 
			
		||||
		)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logger.Error.Println("Failed to daemonize:", err)
 | 
			
		||||
			os.Exit(ExitSetupFailed)
 | 
			
		||||
		}
 | 
			
		||||
		process.Release()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// increase number of go workers (for Go <1.5)
 | 
			
		||||
 | 
			
		||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
			
		||||
 | 
			
		||||
	// create wireguard device
 | 
			
		||||
 | 
			
		||||
	device := NewDevice(tun, logger)
 | 
			
		||||
@ -162,6 +227,10 @@ func main() {
 | 
			
		||||
	term := make(chan os.Signal)
 | 
			
		||||
 | 
			
		||||
	uapi, err := UAPIListen(interfaceName, fileUAPI)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Println("Failed to listen on uapi socket:", err)
 | 
			
		||||
		os.Exit(ExitSetupFailed)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								misc.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								misc.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								peer.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								peer.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ratelimiter
 | 
			
		||||
 | 
			
		||||
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
 | 
			
		||||
 | 
			
		||||
/* This file contains a port of the rate-limiter from the linux kernel version */
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ratelimiter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								send.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								send.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
func signalSend(s chan<- struct{}) {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package tai64n
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package tai64n
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								trie.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								trie.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								tun.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tun.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										205
									
								
								tun_darwin.go
									
									
									
									
									
								
							
							
						
						
									
										205
									
								
								tun_darwin.go
									
									
									
									
									
								
							@ -1,22 +1,17 @@
 | 
			
		||||
/* Copyright (c) 2016, Song Gao <song@gao.io>
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Code from https://github.com/songgao/water
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"golang.org/x/net/ipv4"
 | 
			
		||||
	"golang.org/x/net/ipv6"
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
@ -36,36 +31,32 @@ type sockaddrCtl struct {
 | 
			
		||||
	scReserved [5]uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NativeTUN is a hack to work around the first 4 bytes "packet
 | 
			
		||||
// NativeTun is a hack to work around the first 4 bytes "packet
 | 
			
		||||
// information" because there doesn't seem to be an IFF_NO_PI for darwin.
 | 
			
		||||
type NativeTUN struct {
 | 
			
		||||
type NativeTun struct {
 | 
			
		||||
	name string
 | 
			
		||||
	f    io.ReadWriteCloser
 | 
			
		||||
	fd   *os.File
 | 
			
		||||
	mtu  int
 | 
			
		||||
 | 
			
		||||
	rMu  sync.Mutex
 | 
			
		||||
	rBuf []byte
 | 
			
		||||
 | 
			
		||||
	wMu  sync.Mutex
 | 
			
		||||
	wBuf []byte
 | 
			
		||||
 | 
			
		||||
	events chan TUNEvent
 | 
			
		||||
	errors chan error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var sockaddrCtlSize uintptr = 32
 | 
			
		||||
 | 
			
		||||
func CreateTUN(name string) (ifce TUNDevice, err error) {
 | 
			
		||||
func CreateTUN(name string) (TUNDevice, error) {
 | 
			
		||||
	ifIndex := -1
 | 
			
		||||
	fmt.Sscanf(name, "utun%d", &ifIndex)
 | 
			
		||||
	if ifIndex < 0 {
 | 
			
		||||
		return nil, fmt.Errorf("error parsing interface name %s, must be utun[0-9]+", name)
 | 
			
		||||
	if (name != "utun") {
 | 
			
		||||
		fmt.Sscanf(name, "utun%d", &ifIndex)
 | 
			
		||||
		if ifIndex < 0 {
 | 
			
		||||
			return nil, fmt.Errorf("Interface name must be utun[0-9]*")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("error in unix.Socket: %v", err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var ctlInfo = &struct {
 | 
			
		||||
@ -83,8 +74,7 @@ func CreateTUN(name string) (ifce TUNDevice, err error) {
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		err = errno
 | 
			
		||||
		return nil, fmt.Errorf("error in unix.Syscall(unix.SYS_IOTL, ...): %v", err)
 | 
			
		||||
		return nil, fmt.Errorf("_CTLIOCGINFO: %v", errno)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sc := sockaddrCtl{
 | 
			
		||||
@ -105,148 +95,139 @@ func CreateTUN(name string) (ifce TUNDevice, err error) {
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		err = errno
 | 
			
		||||
		return nil, fmt.Errorf("error in unix.RawSyscall(unix.SYS_CONNECT, ...): %v", err)
 | 
			
		||||
		return nil, fmt.Errorf("SYS_CONNECT: %v", errno)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read (new) name of interface
 | 
			
		||||
	tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""))
 | 
			
		||||
 | 
			
		||||
	var ifName struct {
 | 
			
		||||
		name [16]byte
 | 
			
		||||
	}
 | 
			
		||||
	ifNameSize := uintptr(16)
 | 
			
		||||
 | 
			
		||||
	_, _, errno = unix.Syscall6(
 | 
			
		||||
		unix.SYS_GETSOCKOPT,
 | 
			
		||||
		uintptr(fd),
 | 
			
		||||
		2, /* #define SYSPROTO_CONTROL 2 */
 | 
			
		||||
		2, /* #define UTUN_OPT_IFNAME 2 */
 | 
			
		||||
		uintptr(unsafe.Pointer(&ifName)),
 | 
			
		||||
		uintptr(unsafe.Pointer(&ifNameSize)), 0)
 | 
			
		||||
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		err = errno
 | 
			
		||||
		return nil, fmt.Errorf("error in unix.Syscall6(unix.SYS_GETSOCKOPT, ...): %v", err)
 | 
			
		||||
	if err == nil && name == "utun" {
 | 
			
		||||
		fmt.Printf("OS assigned interface: %s\n", tun.(*NativeTun).name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	device := &NativeTUN{
 | 
			
		||||
		name:   string(ifName.name[:ifNameSize-1 /* -1 is for \0 */]),
 | 
			
		||||
		f:      os.NewFile(uintptr(fd), string(ifName.name[:])),
 | 
			
		||||
	return tun, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
 | 
			
		||||
 | 
			
		||||
	tun := &NativeTun{
 | 
			
		||||
		fd:     file,
 | 
			
		||||
		mtu:    1500,
 | 
			
		||||
		events: make(chan TUNEvent, 10),
 | 
			
		||||
		errors: make(chan error, 1),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// start listener
 | 
			
		||||
	_, err := tun.Name()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func(native *NativeTUN) {
 | 
			
		||||
		// TODO: Fix this very niave implementation
 | 
			
		||||
	// TODO: Fix this very naive implementation
 | 
			
		||||
	go func(tun *NativeTun) {
 | 
			
		||||
		var (
 | 
			
		||||
			statusUp  bool
 | 
			
		||||
			statusMTU int
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		for ; ; time.Sleep(time.Second) {
 | 
			
		||||
			intr, err := net.InterfaceByName(device.name)
 | 
			
		||||
			intr, err := net.InterfaceByName(tun.name)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				native.errors <- err
 | 
			
		||||
				tun.errors <- err
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Up / Down event
 | 
			
		||||
			up := (intr.Flags & net.FlagUp) != 0
 | 
			
		||||
			if up != statusUp && up {
 | 
			
		||||
				native.events <- TUNEventUp
 | 
			
		||||
				tun.events <- TUNEventUp
 | 
			
		||||
			}
 | 
			
		||||
			if up != statusUp && !up {
 | 
			
		||||
				native.events <- TUNEventDown
 | 
			
		||||
				tun.events <- TUNEventDown
 | 
			
		||||
			}
 | 
			
		||||
			statusUp = up
 | 
			
		||||
 | 
			
		||||
			// MTU changes
 | 
			
		||||
			if intr.MTU != statusMTU {
 | 
			
		||||
				native.events <- TUNEventMTUUpdate
 | 
			
		||||
				tun.events <- TUNEventMTUUpdate
 | 
			
		||||
			}
 | 
			
		||||
			statusMTU = intr.MTU
 | 
			
		||||
		}
 | 
			
		||||
	}(device)
 | 
			
		||||
	}(tun)
 | 
			
		||||
 | 
			
		||||
	// set default MTU
 | 
			
		||||
	err = tun.setMTU(DefaultMTU)
 | 
			
		||||
 | 
			
		||||
	err = device.setMTU(DefaultMTU)
 | 
			
		||||
 | 
			
		||||
	return device, err
 | 
			
		||||
	return tun, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ io.ReadWriteCloser = (*NativeTUN)(nil)
 | 
			
		||||
func (tun *NativeTun) Name() (string, error) {
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) Events() chan TUNEvent {
 | 
			
		||||
	return t.events
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) Read(to []byte) (int, error) {
 | 
			
		||||
	t.rMu.Lock()
 | 
			
		||||
	defer t.rMu.Unlock()
 | 
			
		||||
 | 
			
		||||
	if cap(t.rBuf) < len(to)+4 {
 | 
			
		||||
		t.rBuf = make([]byte, len(to)+4)
 | 
			
		||||
	var ifName struct {
 | 
			
		||||
		name [16]byte
 | 
			
		||||
	}
 | 
			
		||||
	t.rBuf = t.rBuf[:len(to)+4]
 | 
			
		||||
	ifNameSize := uintptr(16)
 | 
			
		||||
 | 
			
		||||
	n, err := t.f.Read(t.rBuf)
 | 
			
		||||
	copy(to, t.rBuf[4:])
 | 
			
		||||
	_, _, errno := unix.Syscall6(
 | 
			
		||||
		unix.SYS_GETSOCKOPT,
 | 
			
		||||
		uintptr(tun.fd.Fd()),
 | 
			
		||||
		2, /* #define SYSPROTO_CONTROL 2 */
 | 
			
		||||
		2, /* #define UTUN_OPT_IFNAME 2 */
 | 
			
		||||
		uintptr(unsafe.Pointer(&ifName)),
 | 
			
		||||
		uintptr(unsafe.Pointer(&ifNameSize)), 0)
 | 
			
		||||
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		return "", fmt.Errorf("SYS_GETSOCKOPT: %v", errno)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tun.name = string(ifName.name[:ifNameSize-1])
 | 
			
		||||
	return tun.name, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tun *NativeTun) File() *os.File {
 | 
			
		||||
	return tun.fd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tun *NativeTun) Events() chan TUNEvent {
 | 
			
		||||
	return tun.events
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
 | 
			
		||||
 | 
			
		||||
	buff = buff[offset-4:]
 | 
			
		||||
	n, err := tun.fd.Read(buff[:])
 | 
			
		||||
	if n < 4 {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return n - 4, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) Write(from []byte) (int, error) {
 | 
			
		||||
func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
 | 
			
		||||
 | 
			
		||||
	if len(from) == 0 {
 | 
			
		||||
		return 0, unix.EIO
 | 
			
		||||
	}
 | 
			
		||||
	// reserve space for header
 | 
			
		||||
 | 
			
		||||
	t.wMu.Lock()
 | 
			
		||||
	defer t.wMu.Unlock()
 | 
			
		||||
	buff = buff[offset-4:]
 | 
			
		||||
 | 
			
		||||
	if cap(t.wBuf) < len(from)+4 {
 | 
			
		||||
		t.wBuf = make([]byte, len(from)+4)
 | 
			
		||||
	}
 | 
			
		||||
	t.wBuf = t.wBuf[:len(from)+4]
 | 
			
		||||
	// add packet information header
 | 
			
		||||
 | 
			
		||||
	// determine the IP Family for the NULL L2 Header
 | 
			
		||||
	buff[0] = 0x00
 | 
			
		||||
	buff[1] = 0x00
 | 
			
		||||
	buff[2] = 0x00
 | 
			
		||||
 | 
			
		||||
	ipVer := from[0] >> 4
 | 
			
		||||
	if ipVer == ipv4.Version {
 | 
			
		||||
		t.wBuf[3] = unix.AF_INET
 | 
			
		||||
	} else if ipVer == ipv6.Version {
 | 
			
		||||
		t.wBuf[3] = unix.AF_INET6
 | 
			
		||||
	if buff[4]>>4 == ipv6.Version {
 | 
			
		||||
		buff[3] = unix.AF_INET6
 | 
			
		||||
	} else {
 | 
			
		||||
		return 0, errors.New("Unable to determine IP version from packet.")
 | 
			
		||||
		buff[3] = unix.AF_INET
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copy(t.wBuf[4:], from)
 | 
			
		||||
	// write
 | 
			
		||||
 | 
			
		||||
	n, err := t.f.Write(t.wBuf)
 | 
			
		||||
	return n - 4, err
 | 
			
		||||
	return tun.fd.Write(buff)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) Close() error {
 | 
			
		||||
 | 
			
		||||
	// lock to make sure no read/write is in process.
 | 
			
		||||
 | 
			
		||||
	t.rMu.Lock()
 | 
			
		||||
	defer t.rMu.Unlock()
 | 
			
		||||
 | 
			
		||||
	t.wMu.Lock()
 | 
			
		||||
	defer t.wMu.Unlock()
 | 
			
		||||
 | 
			
		||||
	return t.f.Close()
 | 
			
		||||
func (tun *NativeTun) Close() error {
 | 
			
		||||
	return tun.fd.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) Name() string {
 | 
			
		||||
	return t.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) setMTU(n int) error {
 | 
			
		||||
func (tun *NativeTun) setMTU(n int) error {
 | 
			
		||||
 | 
			
		||||
	// open datagram socket
 | 
			
		||||
 | 
			
		||||
@ -267,7 +248,7 @@ func (t *NativeTUN) setMTU(n int) error {
 | 
			
		||||
	// do ioctl call
 | 
			
		||||
 | 
			
		||||
	var ifr [32]byte
 | 
			
		||||
	copy(ifr[:], t.name)
 | 
			
		||||
	copy(ifr[:], tun.name)
 | 
			
		||||
	binary.LittleEndian.PutUint32(ifr[16:20], uint32(n))
 | 
			
		||||
	_, _, errno := unix.Syscall(
 | 
			
		||||
		unix.SYS_IOCTL,
 | 
			
		||||
@ -277,13 +258,13 @@ func (t *NativeTUN) setMTU(n int) error {
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		return fmt.Errorf("Failed to set MTU on %s", t.name)
 | 
			
		||||
		return fmt.Errorf("Failed to set MTU on %s", tun.name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *NativeTUN) MTU() (int, error) {
 | 
			
		||||
func (tun *NativeTun) MTU() (int, error) {
 | 
			
		||||
 | 
			
		||||
	// open datagram socket
 | 
			
		||||
 | 
			
		||||
@ -302,7 +283,7 @@ func (t *NativeTUN) MTU() (int, error) {
 | 
			
		||||
	// do ioctl call
 | 
			
		||||
 | 
			
		||||
	var ifr [64]byte
 | 
			
		||||
	copy(ifr[:], t.name)
 | 
			
		||||
	copy(ifr[:], tun.name)
 | 
			
		||||
	_, _, errno := unix.Syscall(
 | 
			
		||||
		unix.SYS_IOCTL,
 | 
			
		||||
		uintptr(fd),
 | 
			
		||||
@ -310,7 +291,7 @@ func (t *NativeTUN) MTU() (int, error) {
 | 
			
		||||
		uintptr(unsafe.Pointer(&ifr[0])),
 | 
			
		||||
	)
 | 
			
		||||
	if errno != 0 {
 | 
			
		||||
		return 0, fmt.Errorf("Failed to get MTU on %s", t.name)
 | 
			
		||||
		return 0, fmt.Errorf("Failed to get MTU on %s", tun.name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// convert result to signed 32-bit int
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								uapi.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								uapi.go
									
									
									
									
									
								
							@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								uapi_darwin.go
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								uapi_darwin.go
									
									
									
									
									
								
							@ -1,12 +1,17 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@ -22,6 +27,8 @@ type UAPIListener struct {
 | 
			
		||||
	listener net.Listener // unix socket listener
 | 
			
		||||
	connNew  chan net.Conn
 | 
			
		||||
	connErr  chan error
 | 
			
		||||
	kqueueFd int
 | 
			
		||||
	keventFd int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *UAPIListener) Accept() (net.Conn, error) {
 | 
			
		||||
@ -37,30 +44,27 @@ func (l *UAPIListener) Accept() (net.Conn, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *UAPIListener) Close() error {
 | 
			
		||||
	return l.listener.Close()
 | 
			
		||||
	err1 := unix.Close(l.kqueueFd)
 | 
			
		||||
	err2 := unix.Close(l.keventFd)
 | 
			
		||||
	err3 := l.listener.Close()
 | 
			
		||||
	if err1 != nil {
 | 
			
		||||
		return err1
 | 
			
		||||
	}
 | 
			
		||||
	if err2 != nil {
 | 
			
		||||
		return err2
 | 
			
		||||
	}
 | 
			
		||||
	return err3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *UAPIListener) Addr() net.Addr {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewUAPIListener(name string) (net.Listener, error) {
 | 
			
		||||
func UAPIListen(name string, file *os.File) (net.Listener, error) {
 | 
			
		||||
 | 
			
		||||
	// check if path exist
 | 
			
		||||
	// wrap file in listener
 | 
			
		||||
 | 
			
		||||
	err := os.MkdirAll(socketDirectory, 077)
 | 
			
		||||
	if err != nil && !os.IsExist(err) {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// open UNIX socket
 | 
			
		||||
 | 
			
		||||
	socketPath := path.Join(
 | 
			
		||||
		socketDirectory,
 | 
			
		||||
		fmt.Sprintf(socketName, name),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	listener, err := net.Listen("unix", socketPath)
 | 
			
		||||
	listener, err := net.FileListener(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@ -71,14 +75,43 @@ func NewUAPIListener(name string) (net.Listener, error) {
 | 
			
		||||
		connErr:  make(chan error, 1),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	socketPath := path.Join(
 | 
			
		||||
		socketDirectory,
 | 
			
		||||
		fmt.Sprintf(socketName, name),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// watch for deletion of socket
 | 
			
		||||
 | 
			
		||||
	uapi.kqueueFd, err = unix.Kqueue()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	uapi.keventFd, err = unix.Open(socketDirectory, unix.O_EVTONLY, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		unix.Close(uapi.kqueueFd)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func(l *UAPIListener) {
 | 
			
		||||
		for ; ; time.Sleep(time.Second) {
 | 
			
		||||
			if _, err := os.Stat(socketPath); os.IsNotExist(err) {
 | 
			
		||||
		event := unix.Kevent_t{
 | 
			
		||||
			Ident: uint64(uapi.keventFd),
 | 
			
		||||
			Filter: unix.EVFILT_VNODE,
 | 
			
		||||
			Flags: unix.EV_ADD | unix.EV_ENABLE | unix.EV_ONESHOT,
 | 
			
		||||
			Fflags: unix.NOTE_WRITE,
 | 
			
		||||
		}
 | 
			
		||||
		events := make([]unix.Kevent_t, 1)
 | 
			
		||||
		n := 1
 | 
			
		||||
		var kerr error
 | 
			
		||||
		for {
 | 
			
		||||
			// start with lstat to avoid race condition
 | 
			
		||||
			if _, err := os.Lstat(socketPath); os.IsNotExist(err) {
 | 
			
		||||
				l.connErr <- err
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if kerr != nil || n != 1 {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			n, kerr = unix.Kevent(uapi.kqueueFd, []unix.Kevent_t{event}, events, nil)
 | 
			
		||||
		}
 | 
			
		||||
	}(uapi)
 | 
			
		||||
 | 
			
		||||
@ -97,3 +130,56 @@ func NewUAPIListener(name string) (net.Listener, error) {
 | 
			
		||||
 | 
			
		||||
	return uapi, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UAPIOpen(name string) (*os.File, error) {
 | 
			
		||||
 | 
			
		||||
	// check if path exist
 | 
			
		||||
 | 
			
		||||
	err := os.MkdirAll(socketDirectory, 0600)
 | 
			
		||||
	if err != nil && !os.IsExist(err) {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// open UNIX socket
 | 
			
		||||
 | 
			
		||||
	socketPath := path.Join(
 | 
			
		||||
		socketDirectory,
 | 
			
		||||
		fmt.Sprintf(socketName, name),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	addr, err := net.ResolveUnixAddr("unix", socketPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	listener, err := func() (*net.UnixListener, error) {
 | 
			
		||||
 | 
			
		||||
		// initial connection attempt
 | 
			
		||||
 | 
			
		||||
		listener, err := net.ListenUnix("unix", addr)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			return listener, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check if socket already active
 | 
			
		||||
 | 
			
		||||
		_, err = net.Dial("unix", socketPath)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			return nil, errors.New("unix socket in use")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// cleanup & attempt again
 | 
			
		||||
 | 
			
		||||
		err = os.Remove(socketPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return net.ListenUnix("unix", addr)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return listener.File()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
/* UAPI on windows uses a bidirectional named pipe
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
/* SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2016 Andreas Auernhammer. All Rights Reserved.
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package xchacha20poly1305
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,8 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package xchacha20poly1305
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user