diff options
| author | Odd Stranne <odd@mullvad.net> | 2020-02-13 11:45:24 +0100 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2020-02-13 11:45:24 +0100 |
| commit | 5d894caac066b7f5c3bcb22f765afb9998008340 (patch) | |
| tree | fb3b82d9ac4f5564660f23484e429847f0c5c299 | |
| parent | 63ce03b3ce8de46c39fd8a4ef5e4d49156623dae (diff) | |
| parent | 23fa78689ce2c1db56596b36a84b35f0307cd79b (diff) | |
| download | mullvadvpn-5d894caac066b7f5c3bcb22f765afb9998008340.tar.xz mullvadvpn-5d894caac066b7f5c3bcb22f765afb9998008340.zip | |
Merge branch 'consolidate-wg-wrappers'
27 files changed, 756 insertions, 1016 deletions
diff --git a/.gitattributes b/.gitattributes index d3f9d27b27..56adba2b5b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore index 3a9ed3fa78..155556243c 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ /windows/**/*.user /android/keystore.properties /android/local.properties -/wireguard/wireguard-go/libwg.h +/wireguard/libwg/libwg.h +/wireguard/libwg/libwg.exp +/wireguard/libwg/exports.def **/.vs/ *.bak diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index c8cce94715..607c02349c 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -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"] } diff --git a/talpid-core/src/tunnel/wireguard/logging.rs b/talpid-core/src/tunnel/wireguard/logging.rs new file mode 100644 index 0000000000..5d177441e3 --- /dev/null +++ b/talpid-core/src/tunnel/wireguard/logging.rs @@ -0,0 +1,86 @@ +use super::{Error, Result}; +use chrono; +use parking_lot::Mutex; +use std::{collections::HashMap, fs, io::Write, path::Path}; + +lazy_static::lazy_static! { + static ref LOG_MUTEX: Mutex<HashMap<u32, fs::File>> = Mutex::new(HashMap::new()); +} + +static mut LOG_CONTEXT_NEXT_ORDINAL: u32 = 0; + +pub fn initialize_logging(log_path: Option<&Path>) -> Result<u32> { + let log_file = create_log_file(log_path)?; + + let log_context_ordinal = unsafe { + let mut map = LOG_MUTEX.lock(); + let ordinal = LOG_CONTEXT_NEXT_ORDINAL; + LOG_CONTEXT_NEXT_ORDINAL += 1; + map.insert(ordinal, log_file); + ordinal + }; + + Ok(log_context_ordinal) +} + +#[cfg(target_os = "windows")] +static NULL_DEVICE: &str = "NUL"; + +#[cfg(not(target_os = "windows"))] +static NULL_DEVICE: &str = "/dev/null"; + +fn create_log_file(log_path: Option<&Path>) -> Result<fs::File> { + fs::File::create(log_path.unwrap_or(NULL_DEVICE.as_ref())).map_err(Error::PrepareLogFileError) +} + +pub fn clean_up_logging(ordinal: u32) { + let mut map = LOG_MUTEX.lock(); + map.remove(&ordinal); +} + +// Callback that receives messages from WireGuard +pub unsafe extern "system" fn logging_callback( + level: WgLogLevel, + msg: *const libc::c_char, + context: *mut libc::c_void, +) { + let map = LOG_MUTEX.lock(); + if let Some(mut logfile) = map.get(&(context as u32)) { + let managed_msg = if !msg.is_null() { + #[cfg(not(target_os = "windows"))] + let m = std::ffi::CStr::from_ptr(msg).to_string_lossy().to_string(); + #[cfg(target_os = "windows")] + let m = std::ffi::CStr::from_ptr(msg) + .to_string_lossy() + .to_string() + .replace("\n", "\r\n"); + m + } else { + "Logging message from WireGuard is NULL".to_string() + }; + + let level_str = match level { + WG_GO_LOG_DEBUG => "DEBUG", + WG_GO_LOG_INFO => "INFO", + WG_GO_LOG_ERROR | _ => "ERROR", + }; + + let _ = write!( + logfile, + "{}[{}][{}] {}", + chrono::Local::now().format("[%Y-%m-%d %H:%M:%S%.3f]"), + "wireguard-go", + level_str, + managed_msg + ); + } +} + +// unsafe fn + +pub type WgLogLevel = u32; +// wireguard-go supports log levels 0 through 3 with 3 being the most verbose +// const WG_GO_LOG_SILENT: WgLogLevel = 0; +const WG_GO_LOG_ERROR: WgLogLevel = 1; +const WG_GO_LOG_INFO: WgLogLevel = 2; +const WG_GO_LOG_DEBUG: WgLogLevel = 3; diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs index 6308b1c514..efb44ebbc6 100644 --- a/talpid-core/src/tunnel/wireguard/mod.rs +++ b/talpid-core/src/tunnel/wireguard/mod.rs @@ -15,6 +15,7 @@ use talpid_types::ErrorExt; pub mod config; mod connectivity_check; +mod logging; mod stats; pub mod wireguard_go; @@ -134,7 +135,6 @@ impl WireguardMonitor { route_handle .add_default_route_callback(Some(WgGoTunnel::default_route_changed_callback), ()); - let event_callback = Box::new(on_event.clone()); let (close_msg_sender, close_msg_receiver) = mpsc::channel(); let (pinger_tx, pinger_rx) = mpsc::channel(); diff --git a/talpid-core/src/tunnel/wireguard/wireguard_go.rs b/talpid-core/src/tunnel/wireguard/wireguard_go.rs index f0c79b595d..eb657a04aa 100644 --- a/talpid-core/src/tunnel/wireguard/wireguard_go.rs +++ b/talpid-core/src/tunnel/wireguard/wireguard_go.rs @@ -1,13 +1,19 @@ use super::{stats::Stats, Config, Error, Result, Tunnel}; -use crate::tunnel::tun_provider::TunProvider; +use crate::tunnel::{ + tun_provider::TunProvider, + wireguard::logging::{clean_up_logging, initialize_logging, logging_callback, WgLogLevel}, +}; 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; @@ -17,30 +23,22 @@ use { std::{ net::IpAddr, os::unix::io::{AsRawFd, RawFd}, - ptr, }, }; #[cfg(target_os = "windows")] -use { - crate::winnet::{self, add_device_ip_addresses}, - chrono, - parking_lot::Mutex, - std::{collections::HashMap, fs, io::Write}, -}; - - -#[cfg(target_os = "windows")] -lazy_static::lazy_static! { - static ref LOG_MUTEX: Mutex<HashMap<u32, fs::File>> = Mutex::new(HashMap::new()); -} - -#[cfg(target_os = "windows")] -static mut LOG_CONTEXT_NEXT_ORDINAL: u32 = 0; +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, @@ -49,9 +47,8 @@ pub struct WgGoTunnel { // live long enough and get closed when the tunnel is stopped #[cfg(not(target_os = "windows"))] _tunnel_device: Tun, - // ordinal that maps to fs::File instance, used with logging callback - #[cfg(target_os = "windows")] - log_context_ordinal: u32, + // context that maps to fs::File instance, used with logging callback + _logging_context: LoggingContext, } impl WgGoTunnel { @@ -65,25 +62,27 @@ impl WgGoTunnel { #[cfg_attr(not(target_os = "android"), allow(unused_mut))] 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 iface_name = - CString::new(interface_name.as_bytes()).map_err(Error::InterfaceNameError)?; - - let log_path = log_path.and_then(|path| CString::new(path.to_string_lossy().as_ref()).ok()); - let log_path_ptr = log_path - .as_ref() - .map(|path| path.as_ptr()) - .unwrap_or_else(|| ptr::null()); + let logging_context = initialize_logging(log_path).map(LoggingContext)?; + #[cfg(not(target_os = "android"))] let handle = unsafe { - wgTurnOnWithFd( - iface_name.as_ptr() as *const i8, + wgTurnOn( config.mtu as isize, wg_config_str.as_ptr() as *const i8, tunnel_fd, - log_path_ptr as *const i8, - WG_GO_LOG_DEBUG, + Some(logging_callback), + logging_context.0 as *mut libc::c_void, + ) + }; + + #[cfg(target_os = "android")] + let handle = unsafe { + wgTurnOn( + wg_config_str.as_ptr() as *const i8, + tunnel_fd, + Some(logging_callback), + logging_context.0 as *mut libc::c_void, ) }; @@ -103,6 +102,7 @@ impl WgGoTunnel { interface_name, handle: Some(handle), _tunnel_device: tunnel_device, + _logging_context: logging_context, }) } @@ -113,46 +113,35 @@ impl WgGoTunnel { _tun_provider: &mut TunProvider, _routes: impl Iterator<Item = IpNetwork>, ) -> Result<Self> { - let log_file = prepare_log_file(log_path)?; - - let log_context_ordinal = unsafe { - let mut map = LOG_MUTEX.lock(); - let ordinal = LOG_CONTEXT_NEXT_ORDINAL; - LOG_CONTEXT_NEXT_ORDINAL += 1; - map.insert(ordinal, log_file); - ordinal - }; - let wg_config_str = config.to_userspace_format(); 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).map(LoggingContext)?; let handle = unsafe { wgTurnOn( cstr_iface_name.as_ptr(), config.mtu as i64, wg_config_str.as_ptr(), - Some(Self::logging_callback), - log_context_ordinal as *mut libc::c_void, + Some(logging_callback), + logging_context.0 as *mut libc::c_void, ) }; if handle < 0 { - clean_up_log_file(log_context_ordinal); return Err(Error::FatalStartWireguardError); } if !add_device_ip_addresses(&iface_name, &config.tunnel.addresses) { // Todo: what kind of clean-up is required? - clean_up_log_file(log_context_ordinal); return Err(Error::SetIpAddressesError); } Ok(WgGoTunnel { interface_name: iface_name.clone(), handle: Some(handle), - log_context_ordinal, + _logging_context: logging_context, }) } @@ -190,41 +179,6 @@ impl WgGoTunnel { wgRebindTunnelSocket(address_family.to_windows_proto_enum(), iface_idx); } - // Callback that receives messages from WireGuard - #[cfg(target_os = "windows")] - pub unsafe extern "system" fn logging_callback( - level: WgLogLevel, - msg: *const libc::c_char, - context: *mut libc::c_void, - ) { - let map = LOG_MUTEX.lock(); - if let Some(mut logfile) = map.get(&(context as u32)) { - let managed_msg = if !msg.is_null() { - std::ffi::CStr::from_ptr(msg) - .to_string_lossy() - .to_string() - .replace("\n", "\r\n") - } else { - "Logging message from WireGuard is NULL".to_string() - }; - - let level_str = match level { - WG_GO_LOG_DEBUG => "DEBUG", - WG_GO_LOG_INFO => "INFO", - WG_GO_LOG_ERROR | _ => "ERROR", - }; - - let _ = write!( - logfile, - "{}[{}][{}] {}", - chrono::Local::now().format("[%Y-%m-%d %H:%M:%S%.3f]"), - "wireguard-go", - level_str, - managed_msg - ); - } - } - #[cfg(not(target_os = "windows"))] fn create_tunnel_config(config: &Config, routes: impl Iterator<Item = IpNetwork>) -> TunConfig { let mut dns_servers = vec![IpAddr::V4(config.ipv4_gateway)]; @@ -305,30 +259,14 @@ impl WgGoTunnel { } } -#[cfg(target_os = "windows")] -fn clean_up_log_file(ordinal: u32) { - let mut map = LOG_MUTEX.lock(); - map.remove(&ordinal); -} - impl Drop for WgGoTunnel { fn drop(&mut self) { if let Err(e) = self.stop_tunnel() { log::error!("Failed to stop tunnel - {}", e); } - #[cfg(target_os = "windows")] - clean_up_log_file(self.log_context_ordinal); } } -#[cfg(target_os = "windows")] -static NULL_DEVICE: &str = "NUL"; - -#[cfg(target_os = "windows")] -fn prepare_log_file(log_path: Option<&Path>) -> Result<fs::File> { - fs::File::create(log_path.unwrap_or(NULL_DEVICE.as_ref())).map_err(Error::PrepareLogFileError) -} - impl Tunnel for WgGoTunnel { fn get_interface_name(&self) -> &str { &self.interface_name @@ -370,19 +308,6 @@ impl Tunnel for WgGoTunnel { #[cfg(unix)] pub type Fd = std::os::unix::io::RawFd; -#[cfg(windows)] -pub type Fd = std::os::windows::io::RawHandle; - -type WgLogLevel = u32; -// wireguard-go supports log levels 0 through 3 with 3 being the most verbose -// const WG_GO_LOG_SILENT: WgLogLevel = 0; -#[cfg(target_os = "windows")] -const WG_GO_LOG_ERROR: WgLogLevel = 1; -#[cfg(target_os = "windows")] -const WG_GO_LOG_INFO: WgLogLevel = 2; -const WG_GO_LOG_DEBUG: WgLogLevel = 3; - -#[cfg(target_os = "windows")] pub type LoggingCallback = unsafe extern "system" fn( level: WgLogLevel, msg: *const libc::c_char, @@ -395,15 +320,22 @@ 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_attr(target_os = "android", link_name = "wgTurnOnWithFdAndroid")] - #[cfg(not(target_os = "windows"))] - fn wgTurnOnWithFd( - iface_name: *const i8, + #[cfg(not(any(target_os = "android", target_os = "windows")))] + fn wgTurnOn( mtu: isize, settings: *const i8, fd: Fd, - log_path: *const i8, - logLevel: WgLogLevel, + logging_callback: Option<LoggingCallback>, + logging_context: *mut libc::c_void, + ) -> i32; + + // Android + #[cfg(target_os = "android")] + fn wgTurnOn( + settings: *const i8, + fd: Fd, + logging_callback: Option<LoggingCallback>, + logging_context: *mut libc::c_void, ) -> i32; // Windows @@ -416,7 +348,7 @@ extern "C" { logging_context: *mut libc::c_void, ) -> i32; - // Pass a handle that was created by wgTurnOnWithFd to stop a wireguard tunnel. + // Pass a handle that was created by wgTurnOn to stop a wireguard tunnel. fn wgTurnOff(handle: i32) -> i32; // Returns the file descriptor of the tunnel IPv4 socket. diff --git a/wireguard/build-wireguard-go.sh b/wireguard/build-wireguard-go.sh index f30397e81c..bdfe98d6c5 100755 --- a/wireguard/build-wireguard-go.sh +++ b/wireguard/build-wireguard-go.sh @@ -25,7 +25,7 @@ function win_deduce_lib_executable_path { } function win_gather_export_symbols { - grep -Eo "\/\/export \w+" libwg.go | cut -d' ' -f2 + grep -Eo "\/\/export \w+" libwg.go libwg_windows.go | cut -d' ' -f2 } function win_create_lib_file { @@ -46,7 +46,7 @@ function win_create_lib_file { function build_windows { echo "Building wireguard-go for Windows" - pushd wireguard-go-windows + pushd libwg go build -v -o libwg.dll -buildmode c-shared win_create_lib_file @@ -71,7 +71,7 @@ function unix_target_triple { function build_unix { echo "Building wireguard-go for $1" - pushd wireguard-go + pushd libwg target_triple_dir="../../build/lib/$(unix_target_triple)" mkdir -p $target_triple_dir go build -v -o $target_triple_dir/libwg.a -buildmode c-archive @@ -84,7 +84,7 @@ function build_android { docker run --rm \ -v "$(pwd)/../":/workspace \ - --entrypoint "/workspace/wireguard/wireguard-go/build-android.sh" \ + --entrypoint "/workspace/wireguard/libwg/build-android.sh" \ mullvadvpn/mullvad-android-app-build@sha256:$docker_image_hash } diff --git a/wireguard/wireguard-go/Android.mk b/wireguard/libwg/Android.mk index 6b31ffeb80..6b31ffeb80 100644 --- a/wireguard/wireguard-go/Android.mk +++ b/wireguard/libwg/Android.mk diff --git a/wireguard/libwg/README.md b/wireguard/libwg/README.md new file mode 100644 index 0000000000..e5b96928f7 --- /dev/null +++ b/wireguard/libwg/README.md @@ -0,0 +1,26 @@ +# Introduction + +`libwg` is a tiny wrapper around `wireguard-go`, with the main purpose of providing a simple FFI-friendly interface. + +It currently offers support for the following platforms: + +- Linux +- macOS +- Android +- Windows + +# Organization + +`libwg.go` has shared code that is used on all platforms. + +`libwg_default.go` has default implementations for Linux-based systems. + +`libwg_android.go` has code specifically for Android. + +`libwg_windows.go` has code specifically for Windows. + +# Usage + +Call `wgTurnOn` to create and activate a tunnel. The prototype is different on different platforms, see the code for details. + +Call `wgTurnOff` to destroy the tunnel. diff --git a/wireguard/wireguard-go/build-android.sh b/wireguard/libwg/build-android.sh index 4f1849aa75..4f1849aa75 100755 --- a/wireguard/wireguard-go/build-android.sh +++ b/wireguard/libwg/build-android.sh diff --git a/wireguard/libwg/go.mod b/wireguard/libwg/go.mod new file mode 100644 index 0000000000..02a170a9b5 --- /dev/null +++ b/wireguard/libwg/go.mod @@ -0,0 +1,9 @@ +module github.com/mullvad/mullvadvpn-app/wireguard/libwg + +go 1.13 + +require ( + golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 + golang.zx2c4.com/wireguard v0.0.20200121 + golang.zx2c4.com/wireguard/windows v0.0.38 +) diff --git a/wireguard/libwg/go.sum b/wireguard/libwg/go.sum new file mode 100644 index 0000000000..ee390a307c --- /dev/null +++ b/wireguard/libwg/go.sum @@ -0,0 +1,28 @@ +github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= +github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= +golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20191003171128-d98b1b443823 h1:Ypyv6BNJh07T1pUSrehkLemqPKXhus2MkfktJ91kRh4= +golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.zx2c4.com/wireguard v0.0.20191013-0.20200107164045-4fa2ea6a2dab/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= +golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8= +golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= +golang.zx2c4.com/wireguard/windows v0.0.38 h1:RIXfYUYDCBk5+tsxrnNBRXxIvgnXJc544MrDMFFXj4I= +golang.zx2c4.com/wireguard/windows v0.0.38/go.mod h1:bVbqKzpu4jLrEA2nVNn/WdWyyXGZARZNqkoGHd61DuM= diff --git a/wireguard/wireguard-go/goruntime-boottime-over-monotonic.diff b/wireguard/libwg/goruntime-boottime-over-monotonic.diff index e5c668bde1..e5c668bde1 100644 --- a/wireguard/wireguard-go/goruntime-boottime-over-monotonic.diff +++ b/wireguard/libwg/goruntime-boottime-over-monotonic.diff diff --git a/wireguard/wireguard-go-windows/interfacewatcher.go b/wireguard/libwg/interfacewatcher/interfacewatcher_windows.go index d1a2a008bf..8242ab0ff5 100644 --- a/wireguard/wireguard-go-windows/interfacewatcher.go +++ b/wireguard/libwg/interfacewatcher/interfacewatcher_windows.go @@ -1,10 +1,10 @@ /* SPDX-License-Identifier: MIT * * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - * Copyright (C) 2019 Amagicom AB. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. */ -package main +package interfacewatcher import ( "sync" @@ -13,21 +13,21 @@ import ( "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" ) -type interfaceWatcherEvent struct { - luid winipcfg.LUID - family winipcfg.AddressFamily +type Event struct { + Luid winipcfg.LUID + Family winipcfg.AddressFamily } type interfaceWatcher struct { ready chan bool processingMutex sync.Mutex interfaceChangeCallback *winipcfg.InterfaceChangeCallback - seenEvents []interfaceWatcherEvent - wantedEvents []interfaceWatcherEvent + seenEvents []Event + wantedEvents []Event expired bool } -func watchInterfaces() (*interfaceWatcher, error) { +func NewWatcher() (*interfaceWatcher, error) { iw := &interfaceWatcher{ ready: make(chan bool, 1), expired: false, @@ -45,7 +45,7 @@ func watchInterfaces() (*interfaceWatcher, error) { return } - iw.seenEvents = append(iw.seenEvents, interfaceWatcherEvent{iface.InterfaceLUID, iface.Family}) + iw.seenEvents = append(iw.seenEvents, Event{iface.InterfaceLUID, iface.Family}) if len(iw.wantedEvents) != 0 { iw.evaluateEvents() @@ -79,7 +79,7 @@ func (iw *interfaceWatcher) evaluateEvents() { } // You can only join() once after which the watcher becomes expired. -func (iw *interfaceWatcher) join(wantedEvents []interfaceWatcherEvent, timeoutSeconds int) bool { +func (iw *interfaceWatcher) Join(wantedEvents []Event, timeoutSeconds int) bool { { iw.processingMutex.Lock() @@ -115,7 +115,7 @@ func (iw *interfaceWatcher) join(wantedEvents []interfaceWatcherEvent, timeoutSe return result } -func (iw *interfaceWatcher) destroy() { +func (iw *interfaceWatcher) Destroy() { if iw.interfaceChangeCallback != nil { iw.interfaceChangeCallback.Unregister() iw.interfaceChangeCallback = nil diff --git a/wireguard/libwg/libwg.go b/wireguard/libwg/libwg.go new file mode 100644 index 0000000000..51c01c8976 --- /dev/null +++ b/wireguard/libwg/libwg.go @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package main + +// #include <stdlib.h> +import "C" + +import ( + "bufio" + "bytes" + "runtime" + "unsafe" + + "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 + +func init() { + device.RoamingDisabled = true + tunnels = tunnelcontainer.New() +} + +//export wgTurnOff +func wgTurnOff(tunnelHandle int32) { + { + tunnel, err := tunnels.Remove(tunnelHandle) + if err != nil { + return + } + tunnel.Device.Close() + } + // Calling twice convinces the GC to release NOW. + runtime.GC() + runtime.GC() +} + +//export wgGetConfig +func wgGetConfig(tunnelHandle int32) *C.char { + tunnel, err := tunnels.Get(tunnelHandle) + if err != nil { + return nil + } + settings := new(bytes.Buffer) + writer := bufio.NewWriter(settings) + if err := tunnel.Device.IpcGetOperation(writer); err != nil { + tunnel.Logger.Error.Println("Failed to get config for tunnel: ", err) + return nil + } + writer.Flush() + return C.CString(settings.String()) +} + +//export wgFreePtr +func wgFreePtr(ptr unsafe.Pointer) { + C.free(ptr) +} + +//export wgVersion +func wgVersion() *C.char { + return C.CString(device.WireGuardGoVersion) +} + +func main() {} diff --git a/wireguard/libwg/libwg_android.go b/wireguard/libwg/libwg_android.go new file mode 100644 index 0000000000..56d681b439 --- /dev/null +++ b/wireguard/libwg/libwg_android.go @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package main + +import ( + "C" + "bufio" + "strings" + "unsafe" + + "golang.org/x/sys/unix" + + "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" +) + +// Redefined here because otherwise the compiler doesn't realize it's a type alias for a type that's safe to export. +// Taken from the contained logging package. +type LogSink = unsafe.Pointer +type LogContext = unsafe.Pointer + +//export wgTurnOn +func wgTurnOn(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 ERROR_GENERAL_FAILURE + } + settings := C.GoString(cSettings) + + tunDevice, _, err := tun.CreateUnmonitoredTUNFromFD(fd) + if err != nil { + logger.Error.Println(err) + unix.Close(fd) + if err.Error() == "bad file descriptor" { + return ERROR_INTERMITTENT_FAILURE + } + return ERROR_GENERAL_FAILURE + } + + device := device.NewDevice(tunDevice, logger) + + 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{ + Device: device, + Logger: logger, + } + + handle, err := tunnels.Insert(context) + if err != nil { + logger.Error.Println(err) + device.Close() + return ERROR_GENERAL_FAILURE + } + + return handle +} + +//export wgGetSocketV4 +func wgGetSocketV4(tunnelHandle int32) int32 { + tunnel, err := tunnels.Get(tunnelHandle) + if err != nil { + return ERROR_GENERAL_FAILURE + } + fd, err := tunnel.Device.PeekLookAtSocketFd4() + if err != nil { + return ERROR_GENERAL_FAILURE + } + return int32(fd) +} + +//export wgGetSocketV6 +func wgGetSocketV6(tunnelHandle int32) int32 { + tunnel, err := tunnels.Get(tunnelHandle) + if err != nil { + return ERROR_GENERAL_FAILURE + } + fd, err := tunnel.Device.PeekLookAtSocketFd6() + if err != nil { + return ERROR_GENERAL_FAILURE + } + return int32(fd) +} diff --git a/wireguard/libwg/libwg_default.go b/wireguard/libwg/libwg_default.go new file mode 100644 index 0000000000..0cceee2ff8 --- /dev/null +++ b/wireguard/libwg/libwg_default.go @@ -0,0 +1,77 @@ +// +build darwin linux +// +build !android + +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package main + +// #include <stdlib.h> +import "C" +import ( + "bufio" + "os" + "strings" + "unsafe" + + "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" +) + +// Redefined here because otherwise the compiler doesn't realize it's a type alias for a type that's safe to export. +// Taken from the contained logging package. +type LogSink = unsafe.Pointer +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 ERROR_GENERAL_FAILURE + } + settings := C.GoString(cSettings) + + file := os.NewFile(uintptr(fd), "") + tunDevice, err := tun.CreateTUNFromFile(file, mtu) + if err != nil { + logger.Error.Println(err) + if err.Error() == "bad file descriptor" { + return ERROR_INTERMITTENT_FAILURE + } + return ERROR_GENERAL_FAILURE + } + + device := device.NewDevice(tunDevice, logger) + + 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{ + Device: device, + Logger: logger, + } + + handle, err := tunnels.Insert(context) + if err != nil { + logger.Error.Println(err) + device.Close() + return ERROR_GENERAL_FAILURE + } + + return handle +} diff --git a/wireguard/libwg/libwg_windows.go b/wireguard/libwg/libwg_windows.go new file mode 100644 index 0000000000..ba47c46f2b --- /dev/null +++ b/wireguard/libwg/libwg_windows.go @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package main + +import ( + "C" + "bufio" + "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" +) + +// Redefined here because otherwise the compiler doesn't realize it's a type alias for a type that's safe to export. +// Taken from the contained logging package. +type LogSink = unsafe.Pointer +type LogContext = unsafe.Pointer + +//export wgTurnOn +func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, logContext LogContext) int32 { + logger := logging.NewLogger(logSink, logContext) + + if cIfaceName == nil { + logger.Error.Println("cIfaceName is null") + return ERROR_GENERAL_FAILURE + } + + if cSettings == nil { + logger.Error.Println("cSettings is null") + 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}} + + watcher, err := interfacewatcher.NewWatcher() + if err != nil { + logger.Error.Println(err) + return ERROR_GENERAL_FAILURE + } + defer watcher.Destroy() + + wintun, err := tun.CreateTUNWithRequestedGUID(ifaceName, &networkId, mtu) + if err != nil { + logger.Error.Println("Failed to create tunnel") + logger.Error.Println(err) + return ERROR_GENERAL_FAILURE + } + + nativeTun := wintun.(*tun.NativeTun) + + actualInterfaceName, err := nativeTun.Name() + if err != nil { + nativeTun.Close() + logger.Error.Println("Failed to determine name of wintun adapter") + return ERROR_GENERAL_FAILURE + } + + if actualInterfaceName != ifaceName { + // WireGuard picked a different name for the adapter than the one we expected. + // 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 ERROR_GENERAL_FAILURE + } + + device := device.NewDevice(wintun, logger) + + setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) + if setError != nil { + logger.Error.Println("Failed to set device configuration") + logger.Error.Println(setError) + device.Close() + return ERROR_GENERAL_FAILURE + } + + device.Up() + + interfaces := []interfacewatcher.Event{ + { + Luid: winipcfg.LUID(nativeTun.LUID()), + Family: windows.AF_INET, + }, + { + Luid: winipcfg.LUID(nativeTun.LUID()), + Family: windows.AF_INET6, + }, + } + + logger.Debug.Println("Waiting for interfaces to attach") + + if !watcher.Join(interfaces, 5) { + logger.Error.Println("Failed to wait for IP interfaces to become available") + device.Close() + return ERROR_GENERAL_FAILURE + } + + logger.Debug.Println("Interfaces OK") + + 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 +} + +//export wgRebindTunnelSocket +func wgRebindTunnelSocket(family uint16, interfaceIndex uint32) { + tunnels.ForEach(func(tunnel tunnelcontainer.Context) { + blackhole := (interfaceIndex == 0) + if family == windows.AF_INET { + tunnel.Logger.Info.Printf("Binding v4 socket to interface %d (blackhole=%v)", interfaceIndex, blackhole) + err := tunnel.Device.BindSocketToInterface4(interfaceIndex, blackhole) + if err != nil { + tunnel.Logger.Info.Println(err) + } + } else if family == windows.AF_INET6 { + tunnel.Logger.Info.Printf("Binding v6 socket to interface %d (blackhole=%v)", interfaceIndex, blackhole) + err := tunnel.Device.BindSocketToInterface6(interfaceIndex, blackhole) + if err != nil { + tunnel.Logger.Info.Println(err) + } + } + }) +} diff --git a/wireguard/libwg/logging/logging.go b/wireguard/libwg/logging/logging.go new file mode 100644 index 0000000000..643419bb46 --- /dev/null +++ b/wireguard/libwg/logging/logging.go @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package logging + +// #include <stdlib.h> +// #include <sys/types.h> +// #ifndef WIN32 +// #define __stdcall +// #endif +// typedef void (__stdcall *LogSink)(unsigned int, const char *, void *); +// static void callLogSink(void *logSink, int level, const char *message, void *context) +// { +// ((LogSink)logSink)((unsigned int)level, message, context); +// } +import "C" + +import ( + "log" + "unsafe" + + "golang.zx2c4.com/wireguard/device" +) + +// Define type aliases. +type LogSink = unsafe.Pointer +type LogContext = unsafe.Pointer + +type Logger struct { + sink LogSink + context LogContext + level C.int +} + +func (l *Logger) Write(message []byte) (int, error) { + msg := C.CString(string(message)) + C.callLogSink(l.sink, l.level, msg, l.context) + C.free(unsafe.Pointer(msg)) + return len(message), nil +} + +func NewLogger(logSink LogSink, logContext LogContext) *device.Logger { + logger := new(device.Logger) + + logger.Debug = log.New( + &Logger{sink: logSink, context: logContext, level: device.LogLevelDebug}, + "", + 0, + ) + logger.Info = log.New( + &Logger{sink: logSink, context: logContext, level: device.LogLevelInfo}, + "", + 0, + ) + logger.Error = log.New( + &Logger{sink: logSink, context: logContext, level: device.LogLevelError}, + "", + 0, + ) + + return logger +} diff --git a/wireguard/libwg/tunnelcontainer/tunnelcontainer.go b/wireguard/libwg/tunnelcontainer/tunnelcontainer.go new file mode 100644 index 0000000000..91291dcf4b --- /dev/null +++ b/wireguard/libwg/tunnelcontainer/tunnelcontainer.go @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright (C) 2020 Mullvad VPN AB. All Rights Reserved. + */ + +package tunnelcontainer + +import ( + "net" + "math" + "errors" + + "golang.zx2c4.com/wireguard/device" +) + +type Context struct { + Device *device.Device + Uapi net.Listener + Logger *device.Logger +} + +type Container struct { + tunnels map[int32]Context +} + +func New() Container { + return Container{ + tunnels: make(map[int32]Context), + } +} + +func (tc *Container) Insert(context Context) (int32, error) { + var i int32 + for i = 0; i < math.MaxInt32; i++ { + if _, exists := tc.tunnels[i]; !exists { + break + } + } + + if i == math.MaxInt32 { + return 0, errors.New("Container is full") + } + + tc.tunnels[i] = context + return i, nil +} + +func (tc *Container) Get(handle int32) (Context, error){ + context, ok := tc.tunnels[handle] + if !ok { + return Context{}, errors.New("Invalid context handle") + } + return context, nil +} + +func (tc *Container) Remove(handle int32) (Context, error){ + context, ok := tc.tunnels[handle] + if !ok { + return Context{}, errors.New("Invalid context handle") + } + delete(tc.tunnels, handle) + return context, nil +} + +func (tc *Container) ForEach(callback func(Context)) { + for _, tunnel := range tc.tunnels { + callback(tunnel) + } +} diff --git a/wireguard/wireguard-go-windows/go.mod b/wireguard/wireguard-go-windows/go.mod deleted file mode 100644 index 35b78ec484..0000000000 --- a/wireguard/wireguard-go-windows/go.mod +++ /dev/null @@ -1,21 +0,0 @@ -module github.com/mullvad/mullvadvpn-app/wireguard-go-windows - -go 1.12 - -require ( - github.com/Microsoft/go-winio v0.4.14 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/sirupsen/logrus v1.4.2 // indirect - github.com/stretchr/objx v0.2.0 // indirect - github.com/stretchr/testify v1.4.0 // indirect - golang.org/x/crypto v0.0.0-20200108215511-5d647ca15757 // indirect - golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect - golang.org/x/sys v0.0.0-20200107162124-548cf772de50 - golang.org/x/tools v0.0.0-20200108203644-89082a384178 // indirect - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect - golang.zx2c4.com/wireguard v0.0.20200121 - golang.zx2c4.com/wireguard/windows v0.0.38 - gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/yaml.v2 v2.2.7 // indirect -) diff --git a/wireguard/wireguard-go-windows/go.sum b/wireguard/wireguard-go-windows/go.sum deleted file mode 100644 index 9ed4c430b6..0000000000 --- a/wireguard/wireguard-go-windows/go.sum +++ /dev/null @@ -1,166 +0,0 @@ -github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc= -github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/lxn/walk v0.0.0-20190923074432-2011aca68435/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/walk v0.0.0-20191024083542-9936f81d38c5/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/walk v0.0.0-20191024161928-0ee7d2cded97 h1:3zBUhgnxeLyaImKEtPfKWipiHyI5zYp/V2NN967zPFo= -github.com/lxn/walk v0.0.0-20191024161928-0ee7d2cded97/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/win v0.0.0-20190919090605-24c5960b03d8/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/lxn/win v0.0.0-20191024092953-c0107e6cbbfb/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/lxn/win v0.0.0-20191024121223-cc00c7492fe1 h1:h0wbuSK8xUNmMwDdCxZx2OLdkVck6Bb31zj4CxCN5I4= -github.com/lxn/win v0.0.0-20191024121223-cc00c7492fe1/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss= -golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE= -golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200108215511-5d647ca15757 h1:pJ9H8lzdBh301qPX4VpwJ8TRpLt1IhNK1PxVOICyP54= -golang.org/x/crypto v0.0.0-20200108215511-5d647ca15757/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190502183928-7f726cade0ab h1:9RfW3ktsOZxgo9YNbBAjq1FWzc/igwEcUzZz8IXgSbk= -golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc= -golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2 h1:4dVFTC832rPn4pomLSz1vA+are2+dU19w1H8OngV7nc= -golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190916140828-c8589233b77d h1:mCMDWKhNO37A7GAhOpHPbIw1cjd0V86kX1/WA9c7FZ8= -golang.org/x/net v0.0.0-20190916140828-c8589233b77d/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8= -golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU= -golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4= -golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190830023255-19e00faab6ad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0 h1:7z820YPX9pxWR59qM7BE5+fglp4D/mKqAwCvGt11b+8= -golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5 h1:SW/0nsKCUaozCUtZTakri5laocGx/5bkDSSLrFUsa5s= -golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7 h1:wYqz/tQaWUgGKyx+B/rssSE6wkIKdY5Ee6ryOmzarIg= -golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924062700-2aa67d56cdd7 h1:9Vs0Vm0p/0tnWLBWn79aav6fpcxKjBZbd21Lhxzit4k= -golang.org/x/sys v0.0.0-20190924062700-2aa67d56cdd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae h1:QoJmnb9uyPCrH8GIg9uRLn4Ta45yhcQtpymCd0AavO8= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191104094858-e8c54fb511f6 h1:ZJUmhYTp8GbGC0ViZRc2U+MIYQ8xx9MscsdXnclfIhw= -golang.org/x/sys v0.0.0-20191104094858-e8c54fb511f6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190823093517-aa644d2adf2a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911230505-6bfd74cf029c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190917144518-6c790d64586a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190924052046-3ac2a5bbd98a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191025023517-2077df36852e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.20190517 h1:FQ539AeNmsDek0BvWlaQId62Qe1bJsTwY/hse7SPRus= -golang.zx2c4.com/wireguard v0.0.20190517/go.mod h1:+Ks6M+8QvlG7Er8n35VNd/G5QnUQsypmpxIdPiAg48A= -golang.zx2c4.com/wireguard v0.0.20190805 h1:qPzediAzPEswzRxx2GzzPzNqnwqBZUUxEKTnC+7vjng= -golang.zx2c4.com/wireguard v0.0.20190805/go.mod h1:NFs2tkQT6xXo9kzqGJxObM2MzHhraJi7ZQUmwIqT+tE= -golang.zx2c4.com/wireguard v0.0.20190908 h1:SUoXDdwSMtomLdvke+zz83/u9tNvl4hHmcTIWp38tow= -golang.zx2c4.com/wireguard v0.0.20190908/go.mod h1:LhfXh5z6bLC2lW2ve6BzYZFwnnsXK3OQjySR0Yh2dO8= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190917013833-70f6c42556af h1:0Z1CA9P1u7JLb7ixHREM/XH8wFkM+9t9LrQDeoJkBik= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190917013833-70f6c42556af/go.mod h1:LhfXh5z6bLC2lW2ve6BzYZFwnnsXK3OQjySR0Yh2dO8= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190917053916-01f8ef4e84a0 h1:BVNh+sWik8qlOqQ8Ef64s8bYxv7ka+MkPA7AT+Gk0M8= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190917053916-01f8ef4e84a0/go.mod h1:LhfXh5z6bLC2lW2ve6BzYZFwnnsXK3OQjySR0Yh2dO8= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190922100135-5774e6be91d3 h1:kpi3yed7t47yI5s7u8Z3AXqC0FfMxrCfwIsITux2VrA= -golang.zx2c4.com/wireguard v0.0.20190909-0.20190922100135-5774e6be91d3/go.mod h1:kknHs/HWB+cZKvHHzBldTe9HL6GEOpFswULW8LBwL4I= -golang.zx2c4.com/wireguard v0.0.20191012/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191022095125-f7d0edd2ecf5 h1:tijV0YMbg6JbCA9TNaNVjAK2+6KefpNwF4coc6UkNkQ= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191022095125-f7d0edd2ecf5/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191121140156-3d0bb4c07f85 h1:5N1BJDaQnQAfcqY7MT1QoAAkPOj4gGs4/MC3TsxI12E= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191121140156-3d0bb4c07f85/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20191013-0.20200107164045-4fa2ea6a2dab h1:HVdRO4CGjul3Pj1BD1K5uThcFtrwXEF+F5qI+//V0mw= -golang.zx2c4.com/wireguard v0.0.20191013-0.20200107164045-4fa2ea6a2dab/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8= -golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard/windows v0.0.27 h1:mWNJM+ljcCkHY6tl/yrgaYnzl8GDXkBw/lwVAULZPUQ= -golang.zx2c4.com/wireguard/windows v0.0.27/go.mod h1:52MuSjwe0l0Hiv3wyu3Fq2dRkFXwbooym2zfmItvPGY= -golang.zx2c4.com/wireguard/windows v0.0.34 h1:u/r6uDRXVLZMISJoIMsOvih5hVwR3CIW5c8ZzeNMk6U= -golang.zx2c4.com/wireguard/windows v0.0.34/go.mod h1:dOEC5Ypgn5LE/VR+Fhcs2nDz3BzMYquODzA3JjurnnE= -golang.zx2c4.com/wireguard/windows v0.0.35 h1:egyV5IRbpKr78b+9gkB8AMQ32TtCo0NO//rfh10OSDg= -golang.zx2c4.com/wireguard/windows v0.0.35/go.mod h1:A3MmRXpatlao+Zty3Zxe2nqZ/sQCGYvnMVZ4z7TQY2w= -golang.zx2c4.com/wireguard/windows v0.0.38 h1:RIXfYUYDCBk5+tsxrnNBRXxIvgnXJc544MrDMFFXj4I= -golang.zx2c4.com/wireguard/windows v0.0.38/go.mod h1:bVbqKzpu4jLrEA2nVNn/WdWyyXGZARZNqkoGHd61DuM= -gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= -gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/wireguard/wireguard-go-windows/libwg.go b/wireguard/wireguard-go-windows/libwg.go deleted file mode 100644 index a8a5fe50fd..0000000000 --- a/wireguard/wireguard-go-windows/libwg.go +++ /dev/null @@ -1,290 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * - * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - * Copyright (C) 2019 Amagicom AB. All Rights Reserved. - */ - -package main - -// #include <stdlib.h> -// #include <sys/types.h> -// typedef void (__stdcall *LogSink)(unsigned int, const char *, void *); -// static void callLogSink(void *logSink, int level, const char *message, void *context) -// { -// ((LogSink)logSink)((unsigned int)level, message, context); -// } -import "C" - -import ( - "bufio" - "bytes" - "errors" - "log" - "math" - "net" - "runtime" - "strings" - "unsafe" - - "golang.org/x/sys/windows" - - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/ipc" - "golang.zx2c4.com/wireguard/tun" - "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" -) - -// Define type aliases. -type LogSink = unsafe.Pointer -type LogContext = unsafe.Pointer - -type Logger struct { - sink LogSink - context LogContext - level C.int -} - -func (l *Logger) Write(message []byte) (int, error) { - msg := C.CString(string(message)) - C.callLogSink(l.sink, l.level, msg, l.context) - C.free(unsafe.Pointer(msg)) - return len(message), nil -} - -type TunnelContext struct { - device *device.Device - uapi net.Listener - logger *device.Logger -} - -var tunnels map[int32]TunnelContext - -func init() { - device.RoamingDisabled = true - tunnels = make(map[int32]TunnelContext) -} - -func newLogger(logSink LogSink, logContext LogContext) *device.Logger { - logger := new(device.Logger) - - logger.Debug = log.New( - &Logger{sink: logSink, context: logContext, level: device.LogLevelDebug}, - "", - 0, - ) - logger.Info = log.New( - &Logger{sink: logSink, context: logContext, level: device.LogLevelInfo}, - "", - 0, - ) - logger.Error = log.New( - &Logger{sink: logSink, context: logContext, level: device.LogLevelError}, - "", - 0, - ) - - return logger -} - -// Find next free context slot -func getContextHandle() (int32, error) { - var i int32 - for i = 0; i < math.MaxInt32; i++ { - if _, exists := tunnels[i]; !exists { - break - } - } - - if i == math.MaxInt32 { - return 0, errors.New("Handle table is full") - } - - return i, nil -} - -//export wgTurnOn -func wgTurnOn(cIfaceName *C.char, mtu int, cSettings *C.char, logSink LogSink, logContext LogContext) int32 { - logger := newLogger(logSink, logContext) - - if cIfaceName == nil { - logger.Error.Println("cIfaceName is null") - return -1 - } - - if cSettings == nil { - logger.Error.Println("cSettings is null") - return -1 - } - - contextHandle, err := getContextHandle() - if err != nil { - logger.Error.Println(err) - return -1 - } - - 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 } } - - watcher, err := watchInterfaces() - if err != nil { - logger.Error.Println(err) - return -1 - } - defer watcher.destroy() - - wintun, err := tun.CreateTUNWithRequestedGUID(ifaceName, &networkId, mtu) - if err != nil { - logger.Error.Println("Failed to create tunnel") - logger.Error.Println(err) - return -1 - } - - nativeTun := wintun.(*tun.NativeTun) - - actualInterfaceName, err := nativeTun.Name() - if err != nil { - nativeTun.Close() - logger.Error.Println("Failed to determine name of wintun adapter") - return -1 - } - - if actualInterfaceName != ifaceName { - // WireGuard picked a different name for the adapter than the one we expected. - // 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 - } - - device := device.NewDevice(wintun, logger) - - uapi, err := ipc.UAPIListen(ifaceName) - if err != nil { - logger.Error.Println("Failed to start UAPI") - logger.Error.Println(err) - device.Close() - return -1 - } - - setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) - if setError != nil { - logger.Error.Println("Failed to set device configuration") - logger.Error.Println(setError) - uapi.Close() - device.Close() - return -1 - } - - device.Up() - - interfaces := []interfaceWatcherEvent{ - { - luid: winipcfg.LUID(nativeTun.LUID()), - family: windows.AF_INET, - }, - { - luid: winipcfg.LUID(nativeTun.LUID()), - family: windows.AF_INET6, - }, - } - - logger.Debug.Println("Waiting for interfaces to attach") - - if !watcher.join(interfaces, 5) { - logger.Error.Println("Failed to wait for IP interfaces to become available") - uapi.Close() - device.Close() - return -1 - } - - logger.Debug.Println("Interfaces OK") - - // Service UAPI. - go func() { - for { - conn, err := uapi.Accept() - if err != nil { - logger.Info.Println("UAPI Accept() failed") - logger.Info.Println(err) - return - } - go device.IpcHandle(conn) - } - }() - - tunnels[contextHandle] = TunnelContext{ - device: device, - uapi: uapi, - logger: logger, - } - - return contextHandle -} - -//export wgTurnOff -func wgTurnOff(contextHandle int32) { - { - context, ok := tunnels[contextHandle] - if !ok { - return - } - delete(tunnels, contextHandle) - context.uapi.Close() - context.device.Close() - } - // Calling twice convinces the GC to release NOW. - runtime.GC() - runtime.GC() -} - -//export wgRebindTunnelSocket -func wgRebindTunnelSocket(family uint16, interfaceIndex uint32) { - for _, tunnel := range tunnels { - blackhole := (interfaceIndex == 0) - if family == windows.AF_INET { - tunnel.logger.Info.Printf("Binding v4 socket to interface %d (blackhole=%v)", interfaceIndex, blackhole) - err := tunnel.device.BindSocketToInterface4(interfaceIndex, blackhole) - if err != nil { - tunnel.logger.Info.Println(err) - } - } else if family == windows.AF_INET6 { - tunnel.logger.Info.Printf("Binding v6 socket to interface %d (blackhole=%v)", interfaceIndex, blackhole) - err := tunnel.device.BindSocketToInterface6(interfaceIndex, blackhole) - if err != nil { - tunnel.logger.Info.Println(err) - } - } - } -} - -//export wgVersion -func wgVersion() *C.char { - return C.CString(device.WireGuardGoVersion) -} - -//export wgGetConfig -func wgGetConfig(tunnelHandle int32) *C.char { - tunnel, ok := tunnels[tunnelHandle] - if !ok { - return nil - } - - settings := new(bytes.Buffer) - writer := bufio.NewWriter(settings) - if err := tunnel.device.IpcGetOperation(writer); err != nil { - tunnel.logger.Error.Println("Failed to get config for tunnel: ", err) - return nil - } - writer.Flush() - return C.CString(settings.String()) -} - -//export wgFreePtr -func wgFreePtr(ptr unsafe.Pointer) { - C.free(ptr) -} - -func main() {} diff --git a/wireguard/wireguard-go/go.mod b/wireguard/wireguard-go/go.mod deleted file mode 100644 index 7827c2848e..0000000000 --- a/wireguard/wireguard-go/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module github.com/mullvad/mullvadvpn-app/wireguard-go - -go 1.12 - -require ( - golang.org/x/sys v0.0.0-20191003212358-c178f38b412c - golang.zx2c4.com/wireguard v0.0.20200121 -) diff --git a/wireguard/wireguard-go/go.sum b/wireguard/wireguard-go/go.sum deleted file mode 100644 index 20a3d834b5..0000000000 --- a/wireguard/wireguard-go/go.sum +++ /dev/null @@ -1,38 +0,0 @@ -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56 h1:ZpKuNIejY8P0ExLOVyKhb0WsgG8UdvHXe6TWjY7eL6k= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4= -golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191003171128-d98b1b443823 h1:Ypyv6BNJh07T1pUSrehkLemqPKXhus2MkfktJ91kRh4= -golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5 h1:f005F/Jl5JLP036x7QIvUVhNTqxvSYwFIiyOh2q12iU= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190618155005-516e3c20635f h1:dHNZYIYdq2QuU6w73vZ/DzesPbVlZVYZTtTZmrnsbQ8= -golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191003212358-c178f38b412c h1:6Zx7DRlKXf79yfxuQ/7GqV3w2y7aDsk6bGg0MzF5RVU= -golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.zx2c4.com/wireguard v0.0.20190518-0.20190605110920-108c37a05639 h1:AoX5+g0OBk+KqTTMVl4YPFZ9ioU2tPW1YwtzaVWdORA= -golang.zx2c4.com/wireguard v0.0.20190518-0.20190605110920-108c37a05639/go.mod h1:8X7vp4RrsvM83bde6vQ94DsL4ZpjUViVUym8aa8zGhs= -golang.zx2c4.com/wireguard v0.0.20190805-0.20190805190438-a6aae7b14166 h1:T9pj0ZaaF8Fjy9HraORGjgpY/NxmIFYYc607yVzAsIw= -golang.zx2c4.com/wireguard v0.0.20190805-0.20190805190438-a6aae7b14166/go.mod h1:NFs2tkQT6xXo9kzqGJxObM2MzHhraJi7ZQUmwIqT+tE= -golang.zx2c4.com/wireguard v0.0.20190805-0.20190805190438-b16dba4 h1:vb+nILAYnYsLWs942XZIbSbhHzjezHRl3p7Hqzkx8yE= -golang.zx2c4.com/wireguard v0.0.20190805-0.20190805190438-b16dba4/go.mod h1:NFs2tkQT6xXo9kzqGJxObM2MzHhraJi7ZQUmwIqT+tE= -golang.zx2c4.com/wireguard v0.0.20191012 h1:sdX+y3hrHkW8KJkjY7ZgzpT5Tqo8XnBkH55U1klphko= -golang.zx2c4.com/wireguard v0.0.20191012/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191017134306-ae492d1b3599 h1:fHOjo1GyHRI2q/LcFB9NiFTqXB7WRiu2idShqqTwrZ4= -golang.zx2c4.com/wireguard v0.0.20191013-0.20191017134306-ae492d1b3599/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= -golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8= -golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= diff --git a/wireguard/wireguard-go/libwg.go b/wireguard/wireguard-go/libwg.go deleted file mode 100644 index 5f2366c523..0000000000 --- a/wireguard/wireguard-go/libwg.go +++ /dev/null @@ -1,239 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * - * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - * Copyright (C) 2019 Amagicom AB. All Rights Reserved. - */ - -package main - -// #include <stdlib.h> -import "C" -import ( - "bufio" - "bytes" - "fmt" - "io/ioutil" - "log" - "math" - "net" - "os" - "os/signal" - "runtime" - "strings" - "sync" - "unsafe" - - "golang.org/x/sys/unix" - - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/ipc" - "golang.zx2c4.com/wireguard/tun" -) - -var ( - logFile *os.File - logFilePath *string - logFileLock sync.RWMutex -) - -type FileLogger struct{} - -func (logger FileLogger) Write(buffer []byte) (int, error) { - logFileLock.RLock() - defer logFileLock.RUnlock() - - return logFile.Write(buffer) -} - -type TunnelHandle struct { - device *device.Device - uapi net.Listener -} - -var tunnelHandles map[int32]TunnelHandle - -func init() { - device.RoamingDisabled = true - tunnelHandles = make(map[int32]TunnelHandle) - signals := make(chan os.Signal) - signal.Notify(signals, unix.SIGUSR2) - go func() { - buf := make([]byte, os.Getpagesize()) - for { - select { - case <-signals: - n := runtime.Stack(buf, true) - buf[n] = 0 - log.Println("WireGuard/GoBackend/StackTrace - ", buf) - } - } - }() -} - -func newLogger(newLogFilePath string, level int) *device.Logger { - openLogFile(newLogFilePath) - - logger := &device.Logger{ - Debug: newLogForLevel(device.LogLevelDebug, level), - Info: newLogForLevel(device.LogLevelInfo, level), - Error: newLogForLevel(device.LogLevelError, level), - } - - return logger -} - -func openLogFile(newLogFilePath string) { - logFileLock.Lock() - defer logFileLock.Unlock() - - if logFilePath == nil || *logFilePath != newLogFilePath { - if logFile != nil { - logFile.Close() - } - - logFilePath = &newLogFilePath - backupLogFile(newLogFilePath) - logFile, _ = os.Create(newLogFilePath) - } -} - -func backupLogFile(path string) { - backupPath := fmt.Sprintf("%s.old.log", strings.TrimSuffix(path, ".log")) - - os.Rename(path, backupPath) -} - -func newLogForLevel(level int, maxLevel int) *log.Logger { - if level > maxLevel { - return log.New(ioutil.Discard, "", log.Ldate|log.Ltime) - } - - logger := &FileLogger{} - - prefix := "" - switch level { - case device.LogLevelDebug: - prefix = "DEBUG: " - case device.LogLevelInfo: - prefix = "INFO: " - case device.LogLevelError: - prefix = "ERROR: " - } - - return log.New(logger, prefix, log.Ldate|log.Ltime) -} - -//export wgTurnOnWithFd -func wgTurnOnWithFd(cIfaceName *C.char, mtu int, cSettings *C.char, fd int, logFilePath *C.char, level int) int32 { - - logger := newLogger(C.GoString(logFilePath), level) - if cIfaceName == nil { - logger.Error.Println("cIfaceName is null") - return -1 - } - - if cSettings == nil { - logger.Error.Println("cSettings is null") - return -1 - } - settings := C.GoString(cSettings) - ifaceName := C.GoString(cIfaceName) - - file := os.NewFile(uintptr(fd), "") - tunDevice, err := tun.CreateTUNFromFile(file, mtu) - if err != nil { - logger.Error.Println(err) - if err.Error() == "bad file descriptor" { - return -2 - } - return -1 - } - - device := device.NewDevice(tunDevice, logger) - - var uapi net.Listener - - uapiFile, err := ipc.UAPIOpen(ifaceName) - if err != nil { - logger.Error.Println(err) - } else { - uapi, err = ipc.UAPIListen(ifaceName, uapiFile) - if err != nil { - logger.Error.Println("Failed to start the UAPI") - logger.Error.Println(err) - uapiFile.Close() - } else { - go func() { - for { - conn, err := uapi.Accept() - if err != nil { - return - } - go device.IpcHandle(conn) - } - }() - } - } - - setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) - if setError != nil { - logger.Error.Println(setError) - device.Close() - return -2 - } - var i int32 - for i = 0; i < math.MaxInt32; i++ { - if _, exists := tunnelHandles[i]; !exists { - break - } - } - if i == math.MaxInt32 { - device.Close() - return -1 - } - tunnelHandles[i] = TunnelHandle{device: device, uapi: uapi} - device.Up() - return i -} - -//export wgGetConfig -func wgGetConfig(index int32) *C.char { - handle, ok := tunnelHandles[index] - if !ok { - return nil - } - - settings := new(bytes.Buffer) - writer := bufio.NewWriter(settings) - if err := handle.device.IpcGetOperation(writer); err != nil { - return nil - } - writer.Flush() - return C.CString(settings.String()) -} - -//export wgFreePtr -func wgFreePtr(ptr unsafe.Pointer) { - C.free(ptr) -} - - -//export wgTurnOff -func wgTurnOff(tunnelHandle int32) { - handle, ok := tunnelHandles[tunnelHandle] - if !ok { - return - } - delete(tunnelHandles, tunnelHandle) - if handle.uapi != nil { - handle.uapi.Close() - } - handle.device.Close() -} - -//export wgVersion -func wgVersion() *C.char { - return C.CString(device.WireGuardGoVersion) -} - -func main() {} diff --git a/wireguard/wireguard-go/libwg_android.go b/wireguard/wireguard-go/libwg_android.go deleted file mode 100644 index 778bd59055..0000000000 --- a/wireguard/wireguard-go/libwg_android.go +++ /dev/null @@ -1,114 +0,0 @@ -// +build android -package main - -import ( - "C" - "bufio" - "math" - "net" - "strings" - - "golang.org/x/sys/unix" - - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/ipc" - "golang.zx2c4.com/wireguard/tun" -) - -//export wgGetSocketV4 -func wgGetSocketV4(tunnelHandle int32) int32 { - handle, ok := tunnelHandles[tunnelHandle] - if !ok { - return -1 - } - fd, err := handle.device.PeekLookAtSocketFd4() - if err != nil { - return -1 - } - return int32(fd) -} - -//export wgGetSocketV6 -func wgGetSocketV6(tunnelHandle int32) int32 { - handle, ok := tunnelHandles[tunnelHandle] - if !ok { - return -1 - } - fd, err := handle.device.PeekLookAtSocketFd6() - if err != nil { - return -1 - } - return int32(fd) -} - -//export wgTurnOnWithFdAndroid -func wgTurnOnWithFdAndroid(cIfaceName *C.char, mtu int, cSettings *C.char, fd int, logFilePath *C.char, level int) int32 { - - logger := newLogger(C.GoString(logFilePath), level) - if cIfaceName == nil { - logger.Error.Println("cIfaceName is null") - return -1 - } - - if cSettings == nil { - logger.Error.Println("cSettings is null") - return -1 - } - settings := C.GoString(cSettings) - ifaceName := C.GoString(cIfaceName) - - tunDevice, ifaceName, err := tun.CreateUnmonitoredTUNFromFD(fd) - if err != nil { - logger.Error.Println(err) - unix.Close(fd) - if err.Error() == "bad file descriptor" { - return -2 - } - return -1 - } - device := device.NewDevice(tunDevice, logger) - - var uapi net.Listener - - uapiFile, err := ipc.UAPIOpen(ifaceName) - if err != nil { - logger.Error.Println(err) - } else { - uapi, err = ipc.UAPIListen(ifaceName, uapiFile) - if err != nil { - logger.Error.Println("Failed to start the UAPI") - logger.Error.Println(err) - uapiFile.Close() - } else { - go func() { - for { - conn, err := uapi.Accept() - if err != nil { - return - } - go device.IpcHandle(conn) - } - }() - } - } - - setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) - if setError != nil { - logger.Error.Println(setError) - device.Close() - return -2 - } - var i int32 - for i = 0; i < math.MaxInt32; i++ { - if _, exists := tunnelHandles[i]; !exists { - break - } - } - if i == math.MaxInt32 { - device.Close() - return -1 - } - tunnelHandles[i] = TunnelHandle{device: device, uapi: uapi} - device.Up() - return i -} |
