Big code refactoring #10
							
								
								
									
										3
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							| @@ -3,8 +3,9 @@ | |||||||
|     { |     { | ||||||
|       "name": "Mac", |       "name": "Mac", | ||||||
|       "includePath": [ |       "includePath": [ | ||||||
|         "${workspaceFolder}/node_modules/node-addon-api", |  | ||||||
|         "/usr/local/include/node", |         "/usr/local/include/node", | ||||||
|  |         "/usr/local/lib/zig//libc/include/any-linux-any", | ||||||
|  |         "${workspaceFolder}/node_modules/node-addon-api", | ||||||
|         "${workspaceFolder}/**", |         "${workspaceFolder}/**", | ||||||
|         "${workspaceFolder}/addon" |         "${workspaceFolder}/addon" | ||||||
|       ], |       ], | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ extern "C" { | |||||||
| #include <netinet/in.h> | #include <netinet/in.h> | ||||||
| #include <linux/netlink.h> | #include <linux/netlink.h> | ||||||
| #include <linux/rtnetlink.h> | #include <linux/rtnetlink.h> | ||||||
| #include <malloc.h> | // #include <malloc.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  |  | ||||||
| @@ -74,9 +74,9 @@ void WireguardConfig::getWireguardConfig() { | |||||||
|   else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist"); |   else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist"); | ||||||
|   int status; wg_device *devConfig; wg_peer *peer; |   int status; wg_device *devConfig; wg_peer *peer; | ||||||
|   if ((status = wg_get_device(&devConfig, this->name.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); |   if ((status = wg_get_device(&devConfig, this->name.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); | ||||||
|   if (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(devConfig->private_key); |   if (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) this->privateKey = wgKeys::toString(devConfig->private_key); | ||||||
|   if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) publicKey = wgKeys::toString(devConfig->public_key); |   if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) this->publicKey = wgKeys::toString(devConfig->public_key); | ||||||
|   if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) portListen = devConfig->listen_port; |   if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) this->portListen = devConfig->listen_port; | ||||||
|   this->interfaceAddress.GetInInterface(this->name); |   this->interfaceAddress.GetInInterface(this->name); | ||||||
|  |  | ||||||
|   for ((peer) = (devConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { |   for ((peer) = (devConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { | ||||||
| @@ -291,48 +291,28 @@ typedef struct { | |||||||
|   __u32 data[8]; |   __u32 data[8]; | ||||||
| } inet_prefix; | } inet_prefix; | ||||||
|  |  | ||||||
|  |  | ||||||
| // This function is to open the netlink socket as the name suggests. | // This function is to open the netlink socket as the name suggests. | ||||||
| int netlink_open(struct rtnl_handle* rth) { | void netlink_open(struct rtnl_handle* rth) { | ||||||
|   int addr_len; |   int addr_len; | ||||||
|   memset(rth, 0, sizeof(rth)); |   memset(rth, 0, sizeof(rth)); | ||||||
|  |  | ||||||
|   // Creating the netlink socket of family NETLINK_ROUTE |   // Creating the netlink socket of family NETLINK_ROUTE | ||||||
|  |  | ||||||
|   rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); |   rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | ||||||
|   if (rth->fd < 0) |   if (rth->fd < 0) throw std::string("cannot open netlink socket"); | ||||||
|   { |  | ||||||
|     perror("cannot open netlink socket"); |  | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   memset(&rth->local, 0, sizeof(rth->local)); |   memset(&rth->local, 0, sizeof(rth->local)); | ||||||
|   rth->local.nl_family = AF_NETLINK; |   rth->local.nl_family = AF_NETLINK; | ||||||
|   rth->local.nl_groups = 0; |   rth->local.nl_groups = 0; | ||||||
|  |  | ||||||
|   // Binding the netlink socket |   // Binding the netlink socket | ||||||
|   if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) |   if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) throw std::string("cannot bind netlink socket"); | ||||||
|   { |  | ||||||
|     perror("cannot bind netlink socket"); |  | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   addr_len = sizeof(rth->local); |   addr_len = sizeof(rth->local); | ||||||
|   if (getsockname(rth->fd, (struct sockaddr*)&rth->local, (socklen_t*) &addr_len) < 0) |   if (getsockname(rth->fd, (struct sockaddr*)&rth->local, (socklen_t*) &addr_len) < 0) throw std::string("cannot getsockname"); | ||||||
|   { |   if (addr_len != sizeof(rth->local)) throw std::string("wrong address lenght").append(std::to_string(addr_len)); | ||||||
|     perror("cannot getsockname"); |   if (rth->local.nl_family != AF_NETLINK) throw std::string("wrong address family").append(std::to_string(rth->local.nl_family)); | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   if (addr_len != sizeof(rth->local)) |  | ||||||
|   { |  | ||||||
|     fprintf(stderr, "wrong address lenght %d\n", addr_len); |  | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   if (rth->local.nl_family != AF_NETLINK) |  | ||||||
|   { |  | ||||||
|     fprintf(stderr, "wrong address family %d\n", rth->local.nl_family); |  | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   rth->seq = time(NULL); |   rth->seq = time(NULL); | ||||||
|   return 0; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // This function does the actual reading and writing to the netlink socket | // This function does the actual reading and writing to the netlink socket | ||||||
| @@ -352,12 +332,10 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned | |||||||
|   nladdr.nl_pid = peer; |   nladdr.nl_pid = peer; | ||||||
|   nladdr.nl_groups = groups; |   nladdr.nl_groups = groups; | ||||||
|   n->nlmsg_seq = ++rtnl->seq; |   n->nlmsg_seq = ++rtnl->seq; | ||||||
|   if (answer == NULL) |   if (answer == NULL) n->nlmsg_flags |= NLM_F_ACK; | ||||||
|     n->nlmsg_flags |= NLM_F_ACK; |  | ||||||
|   // Actual sending of the message, status contains success/failure |   // Actual sending of the message, status contains success/failure | ||||||
|   status = sendmsg(rtnl->fd, &msg, 0); |   return sendmsg(rtnl->fd, &msg, 0); | ||||||
|   if (status < 0) |   // if (status < 0) return -1; | ||||||
|     return -1; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // This is the utility function for adding the parameters to the packet. | // This is the utility function for adding the parameters to the packet. | ||||||
| @@ -375,96 +353,25 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) { | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int get_addr_1(inet_prefix *addr, const char *name, int family) { |  | ||||||
|   memset(addr, 0, sizeof(*addr)); |  | ||||||
|  |  | ||||||
|   if (strcmp(name, "default") == 0 || |  | ||||||
|       strcmp(name, "all") == 0 || |  | ||||||
|       strcmp(name, "any") == 0) { |  | ||||||
|     if (family == AF_DECnet) |  | ||||||
|       return -1; |  | ||||||
|     addr->family = family; |  | ||||||
|     addr->bytelen = (family == AF_INET6 ? 16 : 4); |  | ||||||
|     addr->bitlen = -1; |  | ||||||
|     return 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (strchr(name, ':')) { |  | ||||||
|     addr->family = AF_INET6; |  | ||||||
|     if (family != AF_UNSPEC && family != AF_INET6) |  | ||||||
|       return -1; |  | ||||||
|     if (inet_pton(AF_INET6, name, addr->data) <= 0) |  | ||||||
|       return -1; |  | ||||||
|     addr->bytelen = 16; |  | ||||||
|     addr->bitlen = -1; |  | ||||||
|     return 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   addr->family = AF_INET; |  | ||||||
|   if (family != AF_UNSPEC && family != AF_INET) |  | ||||||
|     return -1; |  | ||||||
|  |  | ||||||
|   struct in_addr inAddr; |  | ||||||
|   inet_pton(AF_INET, name, (void*)&inAddr); |  | ||||||
|   memcpy(&addr->data,&inAddr.s_addr, sizeof(inAddr.s_addr)); |  | ||||||
|  |  | ||||||
| //  if (get_addr_ipv4((__u8 *)addr->data, name) <= 0) |  | ||||||
| //    return -1; |  | ||||||
|  |  | ||||||
|   addr->bytelen = 4; |  | ||||||
|   addr->bitlen = -1; |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int get_prefix(inet_prefix *dst, char *arg, int family) { |  | ||||||
|   int err; |  | ||||||
|   unsigned plen; |  | ||||||
|  |  | ||||||
|   memset(dst, 0, sizeof(*dst)); |  | ||||||
|  |  | ||||||
|   if (strcmp(arg, "default") == 0 || |  | ||||||
|       strcmp(arg, "any") == 0 || |  | ||||||
|       strcmp(arg, "all") == 0) { |  | ||||||
|     if (family == AF_DECnet) |  | ||||||
|       return -1; |  | ||||||
|     dst->family = family; |  | ||||||
|     dst->bytelen = 0; |  | ||||||
|     dst->bitlen = 0; |  | ||||||
|     return 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   err = get_addr_1(dst, arg, family); |  | ||||||
|   if (err == 0) { |  | ||||||
|     switch(dst->family) { |  | ||||||
|       case AF_INET6: |  | ||||||
|         dst->bitlen = 128; |  | ||||||
|         break; |  | ||||||
|       case AF_DECnet: |  | ||||||
|         dst->bitlen = 16; |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|       case AF_INET: |  | ||||||
|         dst->bitlen = 32; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return err; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void IpManeger::SetInInterface(std::string interfaceName) { | void IpManeger::SetInInterface(std::string interfaceName) { | ||||||
|   if (this->size() == 0) return; |   if (this->size() == 0) return; | ||||||
|   if (!(WireguardDevices().exist(interfaceName))) throw std::string("Wireguard interface not exists!"); |   if (!(WireguardDevices().exist(interfaceName))) throw std::string("Wireguard interface not exists!"); | ||||||
|   int status; unsigned int ifa_index; wg_device *devConfig;; |   int status; | ||||||
|  |   unsigned int ifa_index; | ||||||
|  |   wg_device *devConfig; | ||||||
|  |  | ||||||
|   if ((status = wg_get_device(&devConfig, interfaceName.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); |   if ((status = wg_get_device(&devConfig, interfaceName.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); | ||||||
|  |  | ||||||
|   ifa_index = devConfig->ifindex; |   ifa_index = devConfig->ifindex; | ||||||
|   free(devConfig); |   free(devConfig); | ||||||
|  |  | ||||||
|  |   for (const auto ip : this->getIpParsed()) { | ||||||
|     struct rtnl_handle * rth; |     struct rtnl_handle * rth; | ||||||
|     rth = (rtnl_handle*)malloc(sizeof(rtnl_handle)); |     rth = (rtnl_handle*)malloc(sizeof(rtnl_handle)); | ||||||
|     netlink_open(rth); |     netlink_open(rth); | ||||||
|   for (const auto ip : this->getIpParsed()) { |     int err; | ||||||
|     inet_prefix lcl; |     inet_prefix lcl; | ||||||
|  |  | ||||||
|     // structure of the netlink packet. |     // structure of the netlink packet. | ||||||
|     struct { |     struct { | ||||||
|       struct nlmsghdr n; |       struct nlmsghdr n; | ||||||
| @@ -482,12 +389,16 @@ void IpManeger::SetInInterface(std::string interfaceName) { | |||||||
|     req.ifa.ifa_index = ifa_index ; // get the loopback index |     req.ifa.ifa_index = ifa_index ; // get the loopback index | ||||||
|     req.ifa.ifa_scope = 0; |     req.ifa.ifa_scope = 0; | ||||||
|  |  | ||||||
|     get_prefix(&lcl, ip.Address.c_str(), req.ifa.ifa_family); |     memset(&lcl, 0, sizeof(lcl)); | ||||||
|  |     lcl.family = req.ifa.ifa_family; | ||||||
|  |     lcl.bytelen = (req.ifa.ifa_family == AF_INET) ? 4 : 16; | ||||||
|  |     lcl.bitlen = (req.ifa.ifa_family == AF_INET) ? 32 : 128; | ||||||
|  |  | ||||||
|  |     if (inet_pton(req.ifa.ifa_family, ip.Address.c_str(), &lcl.data) <= 0) throw std::string("Invalid IP address: ").append(ip.Address); | ||||||
|  |  | ||||||
|     if (req.ifa.ifa_family == AF_UNSPEC) req.ifa.ifa_family = lcl.family; |     if (req.ifa.ifa_family == AF_UNSPEC) req.ifa.ifa_family = lcl.family; | ||||||
|  |  | ||||||
|     struct in_addr inAddr; |     addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); | ||||||
|     inet_pton(req.ifa.ifa_family, ip.Address.c_str(), (void*)&inAddr); |     if ((err = rtnl_talk(rth, &req.n, 0, 0, NULL)) < 0) throw std::string("Cannot set interface IP, code: ").append(std::to_string(err)); | ||||||
|     addattr_l(&req.n, sizeof(req), IFA_LOCAL, &inAddr, sizeof(inAddr)); |  | ||||||
|     if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0); //throw std::string("Cannot set interface ip!"); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -155,9 +155,9 @@ class GetConfig : public WireguardConfig, public Promised { | |||||||
|       if (config.keepInterval >= 0) peerConfig.Set("keepInterval", config.keepInterval); |       if (config.keepInterval >= 0) peerConfig.Set("keepInterval", config.keepInterval); | ||||||
|       if (config.endpoint.length() > 0) peerConfig.Set("endpoint", config.endpoint); |       if (config.endpoint.length() > 0) peerConfig.Set("endpoint", config.endpoint); | ||||||
|  |  | ||||||
|       peerConfig.Set("lastHandshake", Napi::Date::New(env, config.lastHandshake)); |  | ||||||
|       peerConfig.Set("rxBytes", Napi::BigInt::New(env, (uint64_t)config.rxBytes)); |       peerConfig.Set("rxBytes", Napi::BigInt::New(env, (uint64_t)config.rxBytes)); | ||||||
|       peerConfig.Set("txBytes", Napi::BigInt::New(env, (uint64_t)config.txBytes)); |       peerConfig.Set("txBytes", Napi::BigInt::New(env, (uint64_t)config.txBytes)); | ||||||
|  |       peerConfig.Set("lastHandshake", Napi::Date::New(env, config.lastHandshake)); | ||||||
|  |  | ||||||
|       const Napi::Array ips = Napi::Array::New(env); |       const Napi::Array ips = Napi::Array::New(env); | ||||||
|       for (auto &ip : config.allowedIPs) ips.Set(ips.Length(), ip); |       for (auto &ip : config.allowedIPs) ips.Set(ips.Length(), ip); | ||||||
|   | |||||||
| @@ -74,7 +74,7 @@ const addon = (await loadAddon(path.resolve(__dirname, "../binding.yaml"))).wgin | |||||||
|  |  | ||||||
|   /** Kernel wireguard version */ |   /** Kernel wireguard version */ | ||||||
|   driveVersion?: string; |   driveVersion?: string; | ||||||
|   deleteInterface(name: string): Promise<GetConfig>; |   deleteInterface(name: string): Promise<void>; | ||||||
|   listDevices(): Promise<string[]>; |   listDevices(): Promise<string[]>; | ||||||
|   getConfig(name: string): Promise<GetConfig>; |   getConfig(name: string): Promise<GetConfig>; | ||||||
|   setConfig(config: SetConfig): Promise<void>; |   setConfig(config: SetConfig): Promise<void>; | ||||||
|   | |||||||
| @@ -23,7 +23,20 @@ await test("Wireguard interface", async t => { | |||||||
|     ] |     ] | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   await Kernel.setConfig(config); |   const peer2 = await privateKey(); | ||||||
|   console.dir(await Kernel.getConfig(config.name), { depth: null }); |   config.peers[publicKey(peer2)] = { | ||||||
|   await Kernel.deleteInterface(config.name); |     keepInterval: 0, | ||||||
|  |     allowedIPs: [ | ||||||
|  |       "10.66.66.3/32" | ||||||
|  |     ] | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   let skip: string; | ||||||
|  |   await t.test("Create and Set config in interface", async () => Kernel.setConfig(config).catch(err => { skip = "Cannot set wireguard config"; return Promise.reject(err); })); | ||||||
|  |   await t.test("Get config from interface", { skip }, async () => { | ||||||
|  |     const fromInterface = await Kernel.getConfig(config.name); | ||||||
|  |     console.dir(fromInterface, { depth: null }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   // await t.test("Delete interface if exists", { skip }, async () => Kernel.deleteInterface(config.name)); | ||||||
| }); | }); | ||||||
		Reference in New Issue
	
	Block a user