Big code refactoring #10
16
README.md
16
README.md
@ -1 +1,17 @@
|
|||||||
# Wireguard-tools for Nodejs
|
# Wireguard-tools for Nodejs
|
||||||
|
|
||||||
|
Manage your Wireguard interfaces directly from Node.js without any wrappers over `wg` or `wg-quick`
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Licences
|
||||||
|
|
||||||
|
- `Wireguard-tools.js`: GPL-3.0
|
||||||
|
|
||||||
|
### Wireguard
|
||||||
|
|
||||||
|
- `Embeddable-wg-library`: LGPL-2.1+.
|
||||||
|
- `Wireguard-nt`: GPL-2.0
|
||||||
|
- `Wireguard-go`: MIT
|
@ -23,12 +23,10 @@ extern "C" {
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
std::string getWireguardVersion() {
|
std::string getWireguardVersion() {
|
||||||
return "Kernel";
|
return "0.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string driveLoad(std::map<std::string, std::string> load) {
|
std::string driveLoad(std::map<std::string, std::string> load) {}
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireguardDevices::getInterfaces() {
|
void WireguardDevices::getInterfaces() {
|
||||||
size_t len; char *device_name, *devicesList = wg_list_device_names();
|
size_t len; char *device_name, *devicesList = wg_list_device_names();
|
||||||
|
@ -19,7 +19,7 @@ Napi::Object StartAddon(const Napi::Env env, const Napi::Object exports) {
|
|||||||
|
|
||||||
const Napi::Object Constants = Napi::Object::New(env), Userspace = Napi::Object::New(env);
|
const Napi::Object Constants = Napi::Object::New(env), Userspace = Napi::Object::New(env);
|
||||||
if (getWireguardVersion().length() > 0) Constants.Set("driveVersion", getWireguardVersion());
|
if (getWireguardVersion().length() > 0) Constants.Set("driveVersion", getWireguardVersion());
|
||||||
Userspace.Set("driveVersion", WireguardUserspace::getVersion());
|
Userspace.Set("driveVersion", WireguardUserspace::getWireguardVersion());
|
||||||
|
|
||||||
exports.Set("deleteInterface", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
exports.Set("deleteInterface", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||||
const Napi::Env env = info.Env();
|
const Napi::Env env = info.Env();
|
||||||
|
@ -3,11 +3,11 @@ module sirherobrine23.org/Wireguard/wireguard-tools.js/wg-tun
|
|||||||
go 1.21.6
|
go 1.21.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/sys v0.12.0
|
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
golang.org/x/crypto v0.13.0 // indirect
|
golang.org/x/crypto v0.13.0 // indirect
|
||||||
golang.org/x/net v0.15.0 // indirect
|
golang.org/x/net v0.15.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
|
@ -32,21 +32,35 @@ func wgVersion() *C.char {
|
|||||||
return C.CString("unknown")
|
return C.CString("unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export wgSocketDirectory
|
//export existTun
|
||||||
func wgSocketDirectory() *C.char {
|
func existTun(tunName string) bool {
|
||||||
return C.CString(socketDirectory)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export deleteTun
|
|
||||||
func deleteTun(_tunName *C.char) bool {
|
|
||||||
tunName := C.GoString(_tunName)
|
|
||||||
if !existTun(_tunName) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
Files, err := os.ReadDir(socketDirectory)
|
Files, err := os.ReadDir(socketDirectory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
for _, file := range Files {
|
||||||
|
if file.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
splits := strings.Split(file.Name(), "/")
|
||||||
|
splits[len(splits)-1] = strings.TrimSuffix(splits[len(splits)-1], ".sock")
|
||||||
|
if splits[len(splits)-1] == tunName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//export deleteTun
|
||||||
|
func deleteTun(_tunName *C.char) *C.char {
|
||||||
|
tunName := C.GoString(_tunName)
|
||||||
|
if !existTun(tunName) {
|
||||||
|
return C.CString("Tun does not exist")
|
||||||
|
}
|
||||||
|
Files, err := os.ReadDir(socketDirectory)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("Tun does not exist")
|
||||||
|
}
|
||||||
for _, file := range Files {
|
for _, file := range Files {
|
||||||
if file.IsDir() {
|
if file.IsDir() {
|
||||||
continue
|
continue
|
||||||
@ -55,49 +69,21 @@ func deleteTun(_tunName *C.char) bool {
|
|||||||
splits[len(splits)-1] = strings.TrimSuffix(splits[len(splits)-1], ".sock")
|
splits[len(splits)-1] = strings.TrimSuffix(splits[len(splits)-1], ".sock")
|
||||||
if splits[len(splits)-1] == tunName {
|
if splits[len(splits)-1] == tunName {
|
||||||
os.Remove(strings.Join(([]string{socketDirectory, file.Name()}), "/"))
|
os.Remove(strings.Join(([]string{socketDirectory, file.Name()}), "/"))
|
||||||
return true
|
return C.CString("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return C.CString("Tun does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export existTun
|
const levelLog = device.LogLevelVerbose
|
||||||
func existTun(_tunName *C.char) bool {
|
|
||||||
tunName := C.GoString(_tunName)
|
|
||||||
Files, err := os.ReadDir(socketDirectory)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, file := range Files {
|
|
||||||
if file.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
splits := strings.Split(file.Name(), "/")
|
|
||||||
splits[len(splits)-1] = strings.TrimSuffix(splits[len(splits)-1], ".sock")
|
|
||||||
if splits[len(splits)-1] == tunName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getSocketPath
|
|
||||||
func getSocketPath(_tunName *C.char) *C.char {
|
|
||||||
tunName := C.GoString(_tunName)
|
|
||||||
uapi, err := ipc.UAPIOpen(tunName)
|
|
||||||
if err != nil {
|
|
||||||
return C.CString(fmt.Sprintf("Failed to get socket path: %v", err))
|
|
||||||
}
|
|
||||||
return C.CString(strings.Join(([]string{"/", uapi.Name()}), ""))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export createTun
|
//export createTun
|
||||||
func createTun(_tunName *C.char) *C.char {
|
func createTun(_tunName *C.char) *C.char {
|
||||||
interfaceName := C.GoString(_tunName)
|
interfaceName := C.GoString(_tunName)
|
||||||
if existTun(_tunName) {
|
if existTun(interfaceName) {
|
||||||
return C.CString("Tun already exists")
|
return C.CString("Tun already exists")
|
||||||
}
|
}
|
||||||
logger := device.NewLogger(device.LogLevelSilent, fmt.Sprintf("(%s) ", interfaceName))
|
logger := device.NewLogger(levelLog, fmt.Sprintf("(%s) ", interfaceName))
|
||||||
|
|
||||||
// open TUN device (or use supplied fd)
|
// open TUN device (or use supplied fd)
|
||||||
tdev, err := tun.CreateTUN(interfaceName, device.DefaultMTU)
|
tdev, err := tun.CreateTUN(interfaceName, device.DefaultMTU)
|
||||||
@ -133,6 +119,8 @@ func createTun(_tunName *C.char) *C.char {
|
|||||||
uapiListened := uapi.Addr().String()
|
uapiListened := uapi.Addr().String()
|
||||||
|
|
||||||
clean := func() {
|
clean := func() {
|
||||||
|
logger.Verbosef("Shutting down")
|
||||||
|
|
||||||
uapi.Close()
|
uapi.Close()
|
||||||
dev.Close()
|
dev.Close()
|
||||||
tdev.Close()
|
tdev.Close()
|
||||||
@ -145,17 +133,39 @@ func createTun(_tunName *C.char) *C.char {
|
|||||||
for {
|
for {
|
||||||
conn, err := uapi.Accept()
|
conn, err := uapi.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Verbosef("UAPI listener closed")
|
||||||
clean()
|
clean()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
logger.Verbosef("UAPI recive message")
|
||||||
go dev.IpcHandle(conn)
|
go dev.IpcHandle(conn)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
logger.Verbosef("Device started")
|
||||||
<-dev.Wait()
|
<-dev.Wait()
|
||||||
|
logger.Verbosef("Device closing")
|
||||||
clean()
|
clean()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
logger.Verbosef("End start process")
|
||||||
return C.CString(strings.Join(([]string{"/", uapiListened}), ""))
|
return C.CString(strings.Join(([]string{"/", uapiListened}), ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first\0second\0third\0forth\0last\0\0
|
||||||
|
//export listUapis
|
||||||
|
func listUapis() *C.char {
|
||||||
|
Files, err := os.ReadDir(socketDirectory)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
var uapis []string
|
||||||
|
for _, file := range Files {
|
||||||
|
if file.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
uapis = append(uapis, strings.Join(([]string{socketDirectory, file.Name()}), "/"))
|
||||||
|
}
|
||||||
|
return C.CString(strings.Join(uapis, "\x00") + "\x00")
|
||||||
|
}
|
43
addon/userspace/userspace.cpp
Normal file
43
addon/userspace/userspace.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "userspace/wg-go.h"
|
||||||
|
#include "wginterface.hh"
|
||||||
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Get Wireguard-go version
|
||||||
|
std::string WireguardUserspace::getWireguardVersion() {
|
||||||
|
return wgVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create tunel and return path to tunel
|
||||||
|
std::string WireguardUserspace::createWireguardTunnel(std::string wgName) {
|
||||||
|
std::string PathError = createTun((char*)wgName.c_str());
|
||||||
|
if (PathError.rfind("/", 0) != 0) throw PathError;
|
||||||
|
return PathError.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete tunel by name and return true if success
|
||||||
|
void WireguardUserspace::deleteWireguardTunnel(std::string wgName) {
|
||||||
|
std::string deleteStatus = deleteTun((char*)wgName.c_str());
|
||||||
|
if (!deleteStatus.empty()) throw deleteStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> WireguardUserspace::listTunnels() {
|
||||||
|
std::vector<std::string> tunnels;
|
||||||
|
size_t len; char *device_name, *devicesList = listUapis();
|
||||||
|
// Set new devices
|
||||||
|
for (device_name = devicesList, len = 0; (len = strlen(device_name)); device_name += len + 1) tunnels.push_back(std::string(device_name));
|
||||||
|
return tunnels;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WireguardUserspace::checkIfExistTunnel(std::string wgName) {
|
||||||
|
const auto wgTunels = listTunnels();
|
||||||
|
if (wgTunels.size() == 0) return false;
|
||||||
|
for (auto tunelName : wgTunels) {
|
||||||
|
if (tunelName.find_last_of("/") != std::string::npos) tunelName = tunelName.substr(tunelName.find_last_of("/") + 1);
|
||||||
|
if (tunelName.find_last_of(".sock") != std::string::npos) tunelName = tunelName.substr(0, tunelName.find_last_of(".sock"));
|
||||||
|
if (tunelName == wgName) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
@ -1,46 +0,0 @@
|
|||||||
#include "wginterface.hh"
|
|
||||||
#include "userspace/wg-go.h"
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Get Wireguard-go version
|
|
||||||
std::string WireguardUserspace::getVersion() {
|
|
||||||
return wgVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create tunel and return path to tunel
|
|
||||||
std::string WireguardUserspace::createTunel(std::string wgName) {
|
|
||||||
std::string PathError = createTun((char*)wgName.c_str());
|
|
||||||
if (PathError.rfind("/", 0) != 0) throw PathError;
|
|
||||||
return PathError.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete tunel by name and return true if success
|
|
||||||
bool WireguardUserspace::deleteTunel(std::string wgName) {
|
|
||||||
return !!deleteTun((char*)wgName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if tunel exist
|
|
||||||
bool WireguardUserspace::checkTunel(std::string wgName) {
|
|
||||||
return !!existTun((char*)wgName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get uapi folder
|
|
||||||
std::string WireguardUserspace::getUapiDirectory() {
|
|
||||||
return wgSocketDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
// List all tunels
|
|
||||||
std::vector<std::string> WireguardUserspace::listTunels() {
|
|
||||||
std::vector<std::string> tunels;
|
|
||||||
std::filesystem::path p = wgSocketDirectory();
|
|
||||||
if (std::filesystem::exists(p)) {
|
|
||||||
for (const auto & entry : std::filesystem::directory_iterator(p)) {
|
|
||||||
// Absolute path to tunel
|
|
||||||
tunels.push_back(entry.path().string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tunels;
|
|
||||||
}
|
|
16
addon/wg.hh
16
addon/wg.hh
@ -1,6 +1,6 @@
|
|||||||
#ifndef __WG_NODE__
|
#ifndef __WG_NODE__
|
||||||
#define __WG_NODE__
|
#define __WG_NODE__
|
||||||
#include <wginterface.hh>
|
#include "wginterface.hh"
|
||||||
#include <napi.h>
|
#include <napi.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -178,10 +178,16 @@ namespace WgUserspace {
|
|||||||
public:
|
public:
|
||||||
CreateWgTunnel(const Napi::Env &env, const Napi::String &name): Promised(env), tunName{name.Utf8Value()} {}
|
CreateWgTunnel(const Napi::Env &env, const Napi::String &name): Promised(env), tunName{name.Utf8Value()} {}
|
||||||
|
|
||||||
|
void runOk(std::function<void(Napi::Value)> callback) override {
|
||||||
|
Napi::HandleScope scope(Env());
|
||||||
|
callback(Napi::String::New(Env(), tunName));
|
||||||
|
}
|
||||||
|
|
||||||
void Execute() override {
|
void Execute() override {
|
||||||
try {
|
try {
|
||||||
std::string status = WireguardUserspace::createTunel(tunName);
|
std::string status = WireguardUserspace::createWireguardTunnel(tunName);
|
||||||
if (status.rfind("/", 0) != 0) SetError(status);
|
if (status.rfind("/", 0) != 0) SetError(status);
|
||||||
|
else tunName = status;
|
||||||
} catch (std::string &err) { SetError(err); }
|
} catch (std::string &err) { SetError(err); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -193,7 +199,7 @@ namespace WgUserspace {
|
|||||||
|
|
||||||
void Execute() override {
|
void Execute() override {
|
||||||
try {
|
try {
|
||||||
WireguardUserspace::deleteTunel(tunName);
|
WireguardUserspace::deleteWireguardTunnel(tunName);
|
||||||
} catch (std::string &err) { SetError(err); }
|
} catch (std::string &err) { SetError(err); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -206,7 +212,7 @@ namespace WgUserspace {
|
|||||||
|
|
||||||
void Execute() override {
|
void Execute() override {
|
||||||
try {
|
try {
|
||||||
status = WireguardUserspace::checkTunel(tunName);
|
status = WireguardUserspace::checkIfExistTunnel(tunName);
|
||||||
} catch (std::string &err) { SetError(err); }
|
} catch (std::string &err) { SetError(err); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +229,7 @@ namespace WgUserspace {
|
|||||||
|
|
||||||
void Execute() override {
|
void Execute() override {
|
||||||
try {
|
try {
|
||||||
tuns = WireguardUserspace::listTunels();
|
tuns = WireguardUserspace::listTunnels();
|
||||||
if (tuns.size() == 0) SetError("No interfaces found");
|
if (tuns.size() == 0) SetError("No interfaces found");
|
||||||
} catch (std::string &err) { SetError(err); }
|
} catch (std::string &err) { SetError(err); }
|
||||||
}
|
}
|
||||||
|
@ -197,21 +197,18 @@ class WireguardConfig {
|
|||||||
|
|
||||||
namespace WireguardUserspace {
|
namespace WireguardUserspace {
|
||||||
// Get Wireguard-go version
|
// Get Wireguard-go version
|
||||||
std::string getVersion();
|
std::string getWireguardVersion();
|
||||||
|
|
||||||
// Create tunel and return path to tunel
|
// Create tunel and return path to tunel
|
||||||
std::string createTunel(std::string wgName);
|
std::string createWireguardTunnel(std::string wgName);
|
||||||
|
|
||||||
// Delete tunel by name and return true if success
|
// Delete tunel by name and return true if success
|
||||||
bool deleteTunel(std::string wgName);
|
void deleteWireguardTunnel(std::string wgName);
|
||||||
|
|
||||||
// Check if tunel exist
|
|
||||||
bool checkTunel(std::string wgName);
|
|
||||||
|
|
||||||
// Get uapi folder
|
|
||||||
std::string getUapiDirectory();
|
|
||||||
|
|
||||||
// List all tunels
|
// List all tunels
|
||||||
std::vector<std::string> listTunels();
|
std::vector<std::string> listTunnels();
|
||||||
|
|
||||||
|
// Check if tunel exist
|
||||||
|
bool checkIfExistTunnel(std::string wgName);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: wginterface
|
name: wginterface
|
||||||
defines:
|
defines:
|
||||||
- "NODE_VERSION=9"
|
- "NODE_VERSION=8"
|
||||||
- "NAPI_CPP_EXCEPTIONS"
|
- "NAPI_CPP_EXCEPTIONS"
|
||||||
includes:
|
includes:
|
||||||
- node_modules/node-addon-api
|
- node_modules/node-addon-api
|
||||||
@ -8,7 +8,7 @@ includes:
|
|||||||
sources:
|
sources:
|
||||||
- "addon/main.cpp"
|
- "addon/main.cpp"
|
||||||
- "addon/genKey/wgkeys.cpp"
|
- "addon/genKey/wgkeys.cpp"
|
||||||
- "addon/userspace/wginterface.cpp"
|
- "addon/userspace/userspace.cpp"
|
||||||
# Set undefined functions to non supported system
|
# Set undefined functions to non supported system
|
||||||
- "addon/dummy/wginterface.cpp"
|
- "addon/dummy/wginterface.cpp"
|
||||||
prebuild:
|
prebuild:
|
||||||
@ -16,9 +16,10 @@ prebuild:
|
|||||||
cwd: ./addon/userspace/go
|
cwd: ./addon/userspace/go
|
||||||
env:
|
env:
|
||||||
CGO_ENABLED: "1"
|
CGO_ENABLED: "1"
|
||||||
|
LDFLAGS: "-w"
|
||||||
run: |
|
run: |
|
||||||
go build -ldflags=-w -trimpath -v -o ../wg-go.o -buildmode c-archive .
|
go build -trimpath -v -o ../wg-go.o -buildmode c-archive .
|
||||||
mv -vf ../wg-go.o ${BUILDDIR}/wg-go.o
|
mv -fv ../wg-go.o "${BUILDDIR}"
|
||||||
target:
|
target:
|
||||||
linux:
|
linux:
|
||||||
sources:
|
sources:
|
||||||
|
@ -70,9 +70,9 @@ const addon = (await loadAddon(path.resolve(__dirname, "../binding.yaml"))).wgin
|
|||||||
/** Wireguard-go version */
|
/** Wireguard-go version */
|
||||||
driveVersion?: string;
|
driveVersion?: string;
|
||||||
createTunel(wgName: string): Promise<string>;
|
createTunel(wgName: string): Promise<string>;
|
||||||
existTunel(wgName: string): Promise<boolean>;
|
|
||||||
deleteTunel(wgName: string): Promise<void>;
|
deleteTunel(wgName: string): Promise<void>;
|
||||||
listTuns(): Promise<string[]>;
|
checkTunel(wgName: string): Promise<boolean>;
|
||||||
|
listTunels(): Promise<string[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Kernel wireguard version */
|
/** Kernel wireguard version */
|
||||||
@ -107,8 +107,8 @@ export namespace Userspace {
|
|||||||
driveVersion,
|
driveVersion,
|
||||||
createTunel,
|
createTunel,
|
||||||
deleteTunel,
|
deleteTunel,
|
||||||
listTuns,
|
checkTunel,
|
||||||
existTunel,
|
listTunels,
|
||||||
} = userspace || {};
|
} = userspace || {};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -166,50 +166,35 @@ export class Wireguard {
|
|||||||
if (!!Kernel.driveVersion) {
|
if (!!Kernel.driveVersion) {
|
||||||
return Kernel.setConfig({ name, ...this.toJSON() });
|
return Kernel.setConfig({ name, ...this.toJSON() });
|
||||||
}
|
}
|
||||||
if (!(await Userspace.existTunel(name))) await Userspace.createTunel(name);
|
if (!(await Userspace.checkTunel(name))) await Userspace.createTunel(name);
|
||||||
const sockPath = (await Userspace.listTuns()).find((tun) => { let tt = tun.split("/").pop(); return (tt.endsWith(".sock") ? tt.slice(0, -5) : tt) === name; });
|
const sockPath = (await Userspace.listTunels()).find((tun) => { let tt = tun.split("/").pop(); return (tt.endsWith(".sock") ? tt.slice(0, -5) : tt) === name; });
|
||||||
if (!sockPath) throw new Error("Wireguard interface not found");
|
if (!sockPath) throw new Error("Wireguard interface not found");
|
||||||
const sock = net.connect(sockPath);
|
const sock = net.connect(sockPath);
|
||||||
await new Promise<void>((resolve, reject) => sock.once("connect", resolve).once("error", reject));
|
await new Promise<void>((resolve, reject) => sock.once("connect", resolve).once("error", reject));
|
||||||
const rl = readline.createInterface({ input: sock, output: sock });
|
sock.write(`set=1\n`);
|
||||||
let stop = [];
|
if (this.#_privateKey.length == key.Base64Length) sock.write(`\nprivate_key=${key.keyToHex(this.privateKey)}\npublic_key=${key.keyToHex(this.publicKey)}`);
|
||||||
rl.on("line", (line): any => {
|
if (this.#_portListen >= 0) sock.write(`\nlisten_port=${this.#_portListen}`);
|
||||||
if (stop.length) {
|
if (this.#_fwmark >= 0) sock.write(`\nfwmark=${this.#_fwmark}`);
|
||||||
stop.push(line);
|
if (this.address.size > 0) sock.write(`\naddress=${Array.from(this.address).join(",")}`);
|
||||||
if (line === "") sock.end();
|
if (this.#_replacePeers) sock.write(`\nreplace_peers=1`);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (line.startsWith("errno=")) {
|
|
||||||
if (parseInt(line.slice(6)) !== 0) stop.push("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rl.once("close", () => {
|
|
||||||
if (stop.length) throw new Error(stop.join("\n").trim());
|
|
||||||
});
|
|
||||||
rl.write(`set=1\n`);
|
|
||||||
if (this.#_privateKey.length == key.Base64Length) rl.write(`\nprivate_key=${key.keyToHex(this.#_privateKey)}\npublic_key=${key.keyToHex(this.publicKey)}`);
|
|
||||||
if (this.#_portListen >= 0) rl.write(`\nlisten_port=${this.#_portListen}`);
|
|
||||||
if (this.#_fwmark >= 0) rl.write(`\nfwmark=${this.#_fwmark}`);
|
|
||||||
if (this.address.size > 0) rl.write(`\naddress=${Array.from(this.address).join(",")}`);
|
|
||||||
if (this.#_replacePeers) rl.write(`\nreplace_peers=1`);
|
|
||||||
for (const [key, value] of this.#_peers) {
|
for (const [key, value] of this.#_peers) {
|
||||||
rl.write(`\npublic_key=${key}`);
|
sock.write(`\npublic_key=${key}`);
|
||||||
if (value.removeMe) rl.write(`\nremove=${key}`);
|
if (value.removeMe) sock.write(`\nremove=${key}`);
|
||||||
else {
|
else {
|
||||||
if (value.presharedKey) rl.write(`\npreshared_key=${value.presharedKey}`);
|
if (value.presharedKey) sock.write(`\npreshared_key=${value.presharedKey}`);
|
||||||
if (value.keepInterval) rl.write(`\npersistent_keepalive_interval=${value.keepInterval}`);
|
if (value.keepInterval) sock.write(`\npersistent_keepalive_interval=${value.keepInterval}`);
|
||||||
if (value.endpoint) rl.write(`\nendpoint=${value.endpoint}`);
|
if (value.endpoint) sock.write(`\nendpoint=${value.endpoint}`);
|
||||||
if (value.allowedIPs) rl.write(`\nallowed_ips=${value.allowedIPs.join(",")}`);
|
if (value.allowedIPs) sock.write(`\nallowed_ips=${value.allowedIPs.join(",")}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.write("\n\n");
|
sock.end("\n\n");
|
||||||
return new Promise<void>((resolve, reject) => rl.once("close", () => resolve()).once("error", reject));
|
return new Promise<void>((resolve, reject) => sock.once("close", () => resolve()).once("error", reject));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getConfig(name: string) {
|
async getConfig(name: string) {
|
||||||
if (!!Kernel.driveVersion) return Kernel.getConfig(name);
|
if (!!Kernel.driveVersion) return Kernel.getConfig(name);
|
||||||
const sockPath = (await Userspace.listTuns()).find((tun) => { let tt = tun.split("/").pop(); return (tt.endsWith(".sock") ? tt.slice(0, -5) : tt) === name; });
|
const sockPath = (await Userspace.listTunels()).find((tun) => { let tt = tun.split("/").pop(); return (tt.endsWith(".sock") ? tt.slice(0, -5) : tt) === name; });
|
||||||
if (!sockPath) throw new Error("Wireguard interface not found");
|
if (!sockPath) throw new Error("Wireguard interface not found");
|
||||||
const sock = net.connect(sockPath);
|
const sock = net.connect(sockPath);
|
||||||
await new Promise<void>((resolve, reject) => sock.once("connect", resolve).once("error", reject));
|
await new Promise<void>((resolve, reject) => sock.once("connect", resolve).once("error", reject));
|
||||||
@ -229,13 +214,13 @@ export class Wireguard {
|
|||||||
rl.once("close", () => {
|
rl.once("close", () => {
|
||||||
if (stop.length) throw new Error(stop.join("\n").trim());
|
if (stop.length) throw new Error(stop.join("\n").trim());
|
||||||
});
|
});
|
||||||
rl.write("get=1\n\n");
|
sock.write("get=1\n\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteInterface(name: string): Promise<void> {
|
async deleteInterface(name: string): Promise<void> {
|
||||||
if (!!Kernel.driveVersion) return Kernel.deleteInterface(name);
|
if (!!Kernel.driveVersion) return Kernel.deleteInterface(name);
|
||||||
if (await Userspace.existTunel(name)) return Userspace.deleteTunel(name);
|
if (await Userspace.checkTunel(name)) return Userspace.deleteTunel(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default Wireguard;
|
export default Wireguard;
|
Loading…
x
Reference in New Issue
Block a user