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; | ||||||
		Reference in New Issue
	
	Block a user