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
*.rs text eol=lf
wireguard/wireguard-go-windows/go.mod text eol=lf
wireguard/wireguard-go-windows/go.sum text eol=lf
wireguard/libwg/go.mod text eol=lf
wireguard/libwg/go.sum text eol=lf

View File

@ -31,6 +31,7 @@ tokio-core = "0.1"
tokio-executor = "0.1"
uuid = { version = "0.7", features = ["v4"] }
zeroize = "1"
chrono = "0.4"
[target.'cfg(unix)'.dependencies]
@ -66,7 +67,6 @@ tun = "0.4.3"
[target.'cfg(windows)'.dependencies]
chrono = "0.4"
widestring = "0.4"
winreg = "0.6"
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 std::{
ffi::{c_void, CStr, CString},
ffi::{c_void, CStr},
os::raw::c_char,
path::Path,
};
use zeroize::Zeroize;
#[cfg(target_os = "windows")]
use std::ffi::CString;
#[cfg(target_os = "android")]
use crate::tunnel::tun_provider;
@ -20,7 +23,6 @@ use {
std::{
net::IpAddr,
os::unix::io::{AsRawFd, RawFd},
ptr,
},
};
@ -30,6 +32,14 @@ use crate::winnet::{self, add_device_ip_addresses};
#[cfg(not(target_os = "windows"))]
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 {
interface_name: String,
handle: Option<i32>,
@ -38,7 +48,7 @@ pub struct WgGoTunnel {
#[cfg(not(target_os = "windows"))]
_tunnel_device: Tun,
// context that maps to fs::File instance, used with logging callback
logging_context: u32,
_logging_context: LoggingContext,
}
impl WgGoTunnel {
@ -53,7 +63,7 @@ impl WgGoTunnel {
let (mut tunnel_device, tunnel_fd) = Self::get_tunnel(tun_provider, config, routes)?;
let interface_name: String = tunnel_device.interface_name().to_string();
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"))]
let handle = unsafe {
@ -62,7 +72,7 @@ impl WgGoTunnel {
wg_config_str.as_ptr() as *const i8,
tunnel_fd,
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,
tunnel_fd,
Some(logging_callback),
logging_context as *mut libc::c_void,
logging_context.0 as *mut libc::c_void,
)
};
if handle < 0 {
clean_up_logging(logging_context);
// Error values returned from the wireguard-go library
return match handle {
-1 => Err(Error::FatalStartWireguardError),
@ -87,16 +96,13 @@ impl WgGoTunnel {
}
#[cfg(target_os = "android")]
Self::bypass_tunnel_sockets(&mut tunnel_device, handle).or_else(|_| {
clean_up_logging(logging_context);
Err(Error::BypassError)
})?;
Self::bypass_tunnel_sockets(&mut tunnel_device, handle).map_err(Error::BypassError)?;
Ok(WgGoTunnel {
interface_name,
handle: Some(handle),
_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 cstr_iface_name =
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 {
wgTurnOn(
@ -119,25 +125,23 @@ impl WgGoTunnel {
config.mtu as i64,
wg_config_str.as_ptr(),
Some(logging_callback),
logging_context as *mut libc::c_void,
logging_context.0 as *mut libc::c_void,
)
};
if handle < 0 {
clean_up_logging(logging_context);
return Err(Error::FatalStartWireguardError);
}
if !add_device_ip_addresses(&iface_name, &config.tunnel.addresses) {
// Todo: what kind of clean-up is required?
clean_up_logging(logging_context);
return Err(Error::SetIpAddressesError);
}
Ok(WgGoTunnel {
interface_name: iface_name.clone(),
handle: Some(handle),
logging_context,
_logging_context: logging_context,
})
}
@ -260,7 +264,6 @@ impl Drop for WgGoTunnel {
if let Err(e) = self.stop_tunnel() {
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.
// Negative return values signify errors. All error codes are opaque.
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "windows"))]
#[cfg(not(any(target_os = "android", target_os = "windows")))]
fn wgTurnOn(
mtu: isize,
settings: *const i8,

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

View File

@ -14,9 +14,14 @@ import (
"bytes"
"runtime"
"unsafe"
"golang.zx2c4.com/wireguard/device"
"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

View File

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

View File

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

View File

@ -9,15 +9,15 @@ package main
import (
"C"
"bufio"
"unsafe"
"strings"
"unsafe"
"golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/interfacewatcher"
"github.com/mullvad/mullvadvpn-app/wireguard/libwg/logging"
"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 {
logger.Error.Println("cIfaceName is null")
return -1
return ERROR_GENERAL_FAILURE
}
if cSettings == nil {
logger.Error.Println("cSettings is null")
return -1
return ERROR_GENERAL_FAILURE
}
settings := C.GoString(cSettings)
ifaceName := C.GoString(cIfaceName)
// {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()
if err != nil {
logger.Error.Println(err)
return -1
return ERROR_GENERAL_FAILURE
}
defer watcher.Destroy()
@ -59,7 +59,7 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if err != nil {
logger.Error.Println("Failed to create tunnel")
logger.Error.Println(err)
return -1
return ERROR_GENERAL_FAILURE
}
nativeTun := wintun.(*tun.NativeTun)
@ -68,7 +68,7 @@ func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, l
if err != nil {
nativeTun.Close()
logger.Error.Println("Failed to determine name of wintun adapter")
return -1
return ERROR_GENERAL_FAILURE
}
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.
nativeTun.Close()
logger.Error.Println("Failed to create adapter with specific name")
return -1
return ERROR_GENERAL_FAILURE
}
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(setError)
device.Close()
return -1
return ERROR_GENERAL_FAILURE
}
device.Up()
interfaces := []interfacewatcher.Event{
{
Luid: winipcfg.LUID(nativeTun.LUID()),
Luid: winipcfg.LUID(nativeTun.LUID()),
Family: windows.AF_INET,
},
{
Luid: winipcfg.LUID(nativeTun.LUID()),
Luid: winipcfg.LUID(nativeTun.LUID()),
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) {
logger.Error.Println("Failed to wait for IP interfaces to become available")
device.Close()
return -1
return ERROR_GENERAL_FAILURE
}
logger.Debug.Println("Interfaces OK")
context := tunnelcontainer.Context {
context := tunnelcontainer.Context{
Device: device,
Logger: logger,
}
handle, err := tunnels.Insert(context)
if err != nil {
logger.Error.Println(err)
device.Close()
return -1
return ERROR_GENERAL_FAILURE
}
return handle
}