Fix file permissions and all the things

Use chrono in talpid-core on all platforms

Resolve unused imports and android errors

Correct formatting

Fix git attributes to use LF on Windows for go.mod

Fix libwg_default.go

Fix libwg_android.go

Fix logging context management

Fix return values

Fix conditional compilation statement

Fix go formatting
This commit is contained in:
Emīls 2020-02-11 20:09:54 +00:00 committed by Odd Stranne
parent 57f3160281
commit 23fa78689c
8 changed files with 75 additions and 72 deletions

4
.gitattributes vendored
View File

@ -7,5 +7,5 @@
# Use LF for Rust because rustfmt works best like that # Use LF for Rust because rustfmt works best like that
*.rs text eol=lf *.rs text eol=lf
wireguard/wireguard-go-windows/go.mod text eol=lf wireguard/libwg/go.mod text eol=lf
wireguard/wireguard-go-windows/go.sum text eol=lf wireguard/libwg/go.sum text eol=lf

View File

@ -31,6 +31,7 @@ tokio-core = "0.1"
tokio-executor = "0.1" tokio-executor = "0.1"
uuid = { version = "0.7", features = ["v4"] } uuid = { version = "0.7", features = ["v4"] }
zeroize = "1" zeroize = "1"
chrono = "0.4"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
@ -66,7 +67,6 @@ tun = "0.4.3"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
chrono = "0.4"
widestring = "0.4" widestring = "0.4"
winreg = "0.6" winreg = "0.6"
winapi = { version = "0.3.6", features = ["handleapi", "ifdef", "libloaderapi", "netioapi", "synchapi", "winbase", "winuser"] } winapi = { version = "0.3.6", features = ["handleapi", "ifdef", "libloaderapi", "netioapi", "synchapi", "winbase", "winuser"] }

View File

@ -5,12 +5,15 @@ use crate::tunnel::{
}; };
use ipnetwork::IpNetwork; use ipnetwork::IpNetwork;
use std::{ use std::{
ffi::{c_void, CStr, CString}, ffi::{c_void, CStr},
os::raw::c_char, os::raw::c_char,
path::Path, path::Path,
}; };
use zeroize::Zeroize; use zeroize::Zeroize;
#[cfg(target_os = "windows")]
use std::ffi::CString;
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
use crate::tunnel::tun_provider; use crate::tunnel::tun_provider;
@ -20,7 +23,6 @@ use {
std::{ std::{
net::IpAddr, net::IpAddr,
os::unix::io::{AsRawFd, RawFd}, os::unix::io::{AsRawFd, RawFd},
ptr,
}, },
}; };
@ -30,6 +32,14 @@ use crate::winnet::{self, add_device_ip_addresses};
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
const MAX_PREPARE_TUN_ATTEMPTS: usize = 4; const MAX_PREPARE_TUN_ATTEMPTS: usize = 4;
struct LoggingContext(u32);
impl Drop for LoggingContext {
fn drop(&mut self) {
clean_up_logging(self.0);
}
}
pub struct WgGoTunnel { pub struct WgGoTunnel {
interface_name: String, interface_name: String,
handle: Option<i32>, handle: Option<i32>,
@ -38,7 +48,7 @@ pub struct WgGoTunnel {
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
_tunnel_device: Tun, _tunnel_device: Tun,
// context that maps to fs::File instance, used with logging callback // context that maps to fs::File instance, used with logging callback
logging_context: u32, _logging_context: LoggingContext,
} }
impl WgGoTunnel { impl WgGoTunnel {
@ -53,7 +63,7 @@ impl WgGoTunnel {
let (mut tunnel_device, tunnel_fd) = Self::get_tunnel(tun_provider, config, routes)?; let (mut tunnel_device, tunnel_fd) = Self::get_tunnel(tun_provider, config, routes)?;
let interface_name: String = tunnel_device.interface_name().to_string(); let interface_name: String = tunnel_device.interface_name().to_string();
let wg_config_str = config.to_userspace_format(); let wg_config_str = config.to_userspace_format();
let logging_context = initialize_logging(log_path)?; let logging_context = initialize_logging(log_path).map(LoggingContext)?;
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
let handle = unsafe { let handle = unsafe {
@ -62,7 +72,7 @@ impl WgGoTunnel {
wg_config_str.as_ptr() as *const i8, wg_config_str.as_ptr() as *const i8,
tunnel_fd, tunnel_fd,
Some(logging_callback), Some(logging_callback),
logging_context as *mut libc::c_void, logging_context.0 as *mut libc::c_void,
) )
}; };
@ -72,12 +82,11 @@ impl WgGoTunnel {
wg_config_str.as_ptr() as *const i8, wg_config_str.as_ptr() as *const i8,
tunnel_fd, tunnel_fd,
Some(logging_callback), Some(logging_callback),
logging_context as *mut libc::c_void, logging_context.0 as *mut libc::c_void,
) )
}; };
if handle < 0 { if handle < 0 {
clean_up_logging(logging_context);
// Error values returned from the wireguard-go library // Error values returned from the wireguard-go library
return match handle { return match handle {
-1 => Err(Error::FatalStartWireguardError), -1 => Err(Error::FatalStartWireguardError),
@ -87,16 +96,13 @@ impl WgGoTunnel {
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
Self::bypass_tunnel_sockets(&mut tunnel_device, handle).or_else(|_| { Self::bypass_tunnel_sockets(&mut tunnel_device, handle).map_err(Error::BypassError)?;
clean_up_logging(logging_context);
Err(Error::BypassError)
})?;
Ok(WgGoTunnel { Ok(WgGoTunnel {
interface_name, interface_name,
handle: Some(handle), handle: Some(handle),
_tunnel_device: tunnel_device, _tunnel_device: tunnel_device,
logging_context, _logging_context: logging_context,
}) })
} }
@ -111,7 +117,7 @@ impl WgGoTunnel {
let iface_name: String = "wg-mullvad".to_string(); let iface_name: String = "wg-mullvad".to_string();
let cstr_iface_name = let cstr_iface_name =
CString::new(iface_name.as_bytes()).map_err(Error::InterfaceNameError)?; CString::new(iface_name.as_bytes()).map_err(Error::InterfaceNameError)?;
let logging_context = initialize_logging(log_path)?; let logging_context = initialize_logging(log_path).map(LoggingContext)?;
let handle = unsafe { let handle = unsafe {
wgTurnOn( wgTurnOn(
@ -119,25 +125,23 @@ impl WgGoTunnel {
config.mtu as i64, config.mtu as i64,
wg_config_str.as_ptr(), wg_config_str.as_ptr(),
Some(logging_callback), Some(logging_callback),
logging_context as *mut libc::c_void, logging_context.0 as *mut libc::c_void,
) )
}; };
if handle < 0 { if handle < 0 {
clean_up_logging(logging_context);
return Err(Error::FatalStartWireguardError); return Err(Error::FatalStartWireguardError);
} }
if !add_device_ip_addresses(&iface_name, &config.tunnel.addresses) { if !add_device_ip_addresses(&iface_name, &config.tunnel.addresses) {
// Todo: what kind of clean-up is required? // Todo: what kind of clean-up is required?
clean_up_logging(logging_context);
return Err(Error::SetIpAddressesError); return Err(Error::SetIpAddressesError);
} }
Ok(WgGoTunnel { Ok(WgGoTunnel {
interface_name: iface_name.clone(), interface_name: iface_name.clone(),
handle: Some(handle), handle: Some(handle),
logging_context, _logging_context: logging_context,
}) })
} }
@ -260,7 +264,6 @@ impl Drop for WgGoTunnel {
if let Err(e) = self.stop_tunnel() { if let Err(e) = self.stop_tunnel() {
log::error!("Failed to stop tunnel - {}", e); log::error!("Failed to stop tunnel - {}", e);
} }
clean_up_logging(self.logging_context);
} }
} }
@ -317,8 +320,7 @@ extern "C" {
// //
// Positive return values are tunnel handles for this specific wireguard tunnel instance. // Positive return values are tunnel handles for this specific wireguard tunnel instance.
// Negative return values signify errors. All error codes are opaque. // Negative return values signify errors. All error codes are opaque.
#[cfg(not(target_os = "android"))] #[cfg(not(any(target_os = "android", target_os = "windows")))]
#[cfg(not(target_os = "windows"))]
fn wgTurnOn( fn wgTurnOn(
mtu: isize, mtu: isize,
settings: *const i8, settings: *const i8,

0
wireguard/libwg/build-android.sh Normal file → Executable file
View File

View File

@ -14,9 +14,14 @@ import (
"bytes" "bytes"
"runtime" "runtime"
"unsafe" "unsafe"
"golang.zx2c4.com/wireguard/device"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer"
"golang.zx2c4.com/wireguard/device"
)
const (
ERROR_GENERAL_FAILURE = -1
ERROR_INTERMITTENT_FAILURE = -2
) )
var tunnels tunnelcontainer.Container var tunnels tunnelcontainer.Container

View File

@ -11,7 +11,7 @@ import (
"bufio" "bufio"
"strings" "strings"
"unsafe" "unsafe"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/device"
@ -26,11 +26,6 @@ import (
type LogSink = unsafe.Pointer type LogSink = unsafe.Pointer
type LogContext = unsafe.Pointer type LogContext = unsafe.Pointer
const (
ERROR_GENERAL_FAILURE = -1
ERROR_INTERMITTENT_FAILURE = -2
)
//export wgTurnOn //export wgTurnOn
func wgTurnOn(cSettings *C.char, fd int, logSink LogSink, logContext LogContext) int32 { func wgTurnOn(cSettings *C.char, fd int, logSink LogSink, logContext LogContext) int32 {
logger := logging.NewLogger(logSink, logContext) logger := logging.NewLogger(logSink, logContext)
@ -53,27 +48,27 @@ func wgTurnOn(cSettings *C.char, fd int, logSink LogSink, logContext LogContext)
device := device.NewDevice(tunDevice, logger) device := device.NewDevice(tunDevice, logger)
err = device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) setErr := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings)))
if err != nil { if setErr != nil {
logger.Error.Println(err) logger.Error.Println(setErr)
device.Close() device.Close()
return ERROR_INTERMITTENT_FAILURE return ERROR_INTERMITTENT_FAILURE
} }
device.Up() device.Up()
context := tunnelcontainer.Context { context := tunnelcontainer.Context{
Device: device, Device: device,
Logger: logger, Logger: logger,
} }
handle, err := tunnels.Insert(context) handle, err := tunnels.Insert(context)
if err != nil { if err != nil {
logger.Error.Println(err) logger.Error.Println(err)
device.Close() device.Close()
return ERROR_GENERAL_FAILURE return ERROR_GENERAL_FAILURE
} }
return handle return handle
} }
@ -81,11 +76,11 @@ func wgTurnOn(cSettings *C.char, fd int, logSink LogSink, logContext LogContext)
func wgGetSocketV4(tunnelHandle int32) int32 { func wgGetSocketV4(tunnelHandle int32) int32 {
tunnel, err := tunnels.Get(tunnelHandle) tunnel, err := tunnels.Get(tunnelHandle)
if err != nil { if err != nil {
return -1 return ERROR_GENERAL_FAILURE
} }
fd, err := tunnel.Device.PeekLookAtSocketFd4() fd, err := tunnel.Device.PeekLookAtSocketFd4()
if err != nil { if err != nil {
return -1 return ERROR_GENERAL_FAILURE
} }
return int32(fd) return int32(fd)
} }
@ -94,11 +89,11 @@ func wgGetSocketV4(tunnelHandle int32) int32 {
func wgGetSocketV6(tunnelHandle int32) int32 { func wgGetSocketV6(tunnelHandle int32) int32 {
tunnel, err := tunnels.Get(tunnelHandle) tunnel, err := tunnels.Get(tunnelHandle)
if err != nil { if err != nil {
return -1 return ERROR_GENERAL_FAILURE
} }
fd, err := tunnel.Device.PeekLookAtSocketFd6() fd, err := tunnel.Device.PeekLookAtSocketFd6()
if err != nil { if err != nil {
return -1 return ERROR_GENERAL_FAILURE
} }
return int32(fd) return int32(fd)
} }

View File

@ -19,7 +19,7 @@ import (
"golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/tun"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/logging" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/logging"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer"
) )
@ -31,11 +31,12 @@ type LogContext = unsafe.Pointer
//export wgTurnOn //export wgTurnOn
func wgTurnOn(mtu int, cSettings *C.char, fd int, logSink LogSink, logContext LogContext) int32 { func wgTurnOn(mtu int, cSettings *C.char, fd int, logSink LogSink, logContext LogContext) int32 {
logger := logging.NewLogger(logSink, logContext) logger := logging.NewLogger(logSink, logContext)
if cSettings == nil { if cSettings == nil {
logger.Error.Println("cSettings is null") logger.Error.Println("cSettings is null")
return -1 return ERROR_GENERAL_FAILURE
} }
settings := C.GoString(cSettings) settings := C.GoString(cSettings)
@ -44,33 +45,33 @@ func wgTurnOn(mtu int, cSettings *C.char, fd int, logSink LogSink, logContext Lo
if err != nil { if err != nil {
logger.Error.Println(err) logger.Error.Println(err)
if err.Error() == "bad file descriptor" { if err.Error() == "bad file descriptor" {
return -2 return ERROR_INTERMITTENT_FAILURE
} }
return -1 return ERROR_GENERAL_FAILURE
} }
device := device.NewDevice(tunDevice, logger) device := device.NewDevice(tunDevice, logger)
err = device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) setErr := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings)))
if err != nil { if setErr != nil {
logger.Error.Println(err) logger.Error.Println(setErr)
device.Close() device.Close()
return -2 return ERROR_INTERMITTENT_FAILURE
} }
device.Up() device.Up()
context := tunnelcontainer.Context { context := tunnelcontainer.Context{
Device: device, Device: device,
Logger: logger, Logger: logger,
} }
handle, err := tunnels.Insert(context) handle, err := tunnels.Insert(context)
if err != nil { if err != nil {
logger.Error.Println(err) logger.Error.Println(err)
device.Close() device.Close()
return -1 return ERROR_GENERAL_FAILURE
} }
return handle return handle
} }

View File

@ -9,15 +9,15 @@ package main
import ( import (
"C" "C"
"bufio" "bufio"
"unsafe"
"strings" "strings"
"unsafe"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/interfacewatcher" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/interfacewatcher"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/logging" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/logging"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer" "github.com/mullvad/mullvadvpn-app/wireguard/libwg/tunnelcontainer"
@ -34,24 +34,24 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if cIfaceName == nil { if cIfaceName == nil {
logger.Error.Println("cIfaceName is null") logger.Error.Println("cIfaceName is null")
return -1 return ERROR_GENERAL_FAILURE
} }
if cSettings == nil { if cSettings == nil {
logger.Error.Println("cSettings is null") logger.Error.Println("cSettings is null")
return -1 return ERROR_GENERAL_FAILURE
} }
settings := C.GoString(cSettings) settings := C.GoString(cSettings)
ifaceName := C.GoString(cIfaceName) ifaceName := C.GoString(cIfaceName)
// {AFE43773-E1F8-4EBB-8536-576AB86AFE9A} // {AFE43773-E1F8-4EBB-8536-576AB86AFE9A}
networkId := windows.GUID { 0xafe43773, 0xe1f8, 0x4ebb, [8]byte{ 0x85, 0x36, 0x57, 0x6a, 0xb8, 0x6a, 0xfe, 0x9a } } networkId := windows.GUID{0xafe43773, 0xe1f8, 0x4ebb, [8]byte{0x85, 0x36, 0x57, 0x6a, 0xb8, 0x6a, 0xfe, 0x9a}}
watcher, err := interfacewatcher.NewWatcher() watcher, err := interfacewatcher.NewWatcher()
if err != nil { if err != nil {
logger.Error.Println(err) logger.Error.Println(err)
return -1 return ERROR_GENERAL_FAILURE
} }
defer watcher.Destroy() defer watcher.Destroy()
@ -59,7 +59,7 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if err != nil { if err != nil {
logger.Error.Println("Failed to create tunnel") logger.Error.Println("Failed to create tunnel")
logger.Error.Println(err) logger.Error.Println(err)
return -1 return ERROR_GENERAL_FAILURE
} }
nativeTun := wintun.(*tun.NativeTun) nativeTun := wintun.(*tun.NativeTun)
@ -68,7 +68,7 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if err != nil { if err != nil {
nativeTun.Close() nativeTun.Close()
logger.Error.Println("Failed to determine name of wintun adapter") logger.Error.Println("Failed to determine name of wintun adapter")
return -1 return ERROR_GENERAL_FAILURE
} }
if actualInterfaceName != ifaceName { if actualInterfaceName != ifaceName {
@ -76,7 +76,7 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
// This indicates there is already an adapter with the name we intended to use. // This indicates there is already an adapter with the name we intended to use.
nativeTun.Close() nativeTun.Close()
logger.Error.Println("Failed to create adapter with specific name") logger.Error.Println("Failed to create adapter with specific name")
return -1 return ERROR_GENERAL_FAILURE
} }
device := device.NewDevice(wintun, logger) device := device.NewDevice(wintun, logger)
@ -86,18 +86,18 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
logger.Error.Println("Failed to set device configuration") logger.Error.Println("Failed to set device configuration")
logger.Error.Println(setError) logger.Error.Println(setError)
device.Close() device.Close()
return -1 return ERROR_GENERAL_FAILURE
} }
device.Up() device.Up()
interfaces := []interfacewatcher.Event{ interfaces := []interfacewatcher.Event{
{ {
Luid: winipcfg.LUID(nativeTun.LUID()), Luid: winipcfg.LUID(nativeTun.LUID()),
Family: windows.AF_INET, Family: windows.AF_INET,
}, },
{ {
Luid: winipcfg.LUID(nativeTun.LUID()), Luid: winipcfg.LUID(nativeTun.LUID()),
Family: windows.AF_INET6, Family: windows.AF_INET6,
}, },
} }
@ -107,23 +107,23 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if !watcher.Join(interfaces, 5) { if !watcher.Join(interfaces, 5) {
logger.Error.Println("Failed to wait for IP interfaces to become available") logger.Error.Println("Failed to wait for IP interfaces to become available")
device.Close() device.Close()
return -1 return ERROR_GENERAL_FAILURE
} }
logger.Debug.Println("Interfaces OK") logger.Debug.Println("Interfaces OK")
context := tunnelcontainer.Context { context := tunnelcontainer.Context{
Device: device, Device: device,
Logger: logger, Logger: logger,
} }
handle, err := tunnels.Insert(context) handle, err := tunnels.Insert(context)
if err != nil { if err != nil {
logger.Error.Println(err) logger.Error.Println(err)
device.Close() device.Close()
return -1 return ERROR_GENERAL_FAILURE
} }
return handle return handle
} }