Big code refactoring #10

Merged
Sirherobrine23 merged 15 commits from code_refactoring into main 2024-03-15 04:08:27 +00:00
5 changed files with 58 additions and 133 deletions
Showing only changes of commit a0e8403160 - Show all commits

@ -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,101 +353,30 @@ 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);
struct rtnl_handle * rth;
rth = (rtnl_handle*)malloc(sizeof(rtnl_handle));
netlink_open(rth);
for (const auto ip : this->getIpParsed()) { for (const auto ip : this->getIpParsed()) {
struct rtnl_handle * rth;
rth = (rtnl_handle*)malloc(sizeof(rtnl_handle));
netlink_open(rth);
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;
struct ifaddrmsg ifa; struct ifaddrmsg ifa;
char buf[1024]; char buf[1024];
} req; } req;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
@ -480,14 +387,18 @@ void IpManeger::SetInInterface(std::string interfaceName) {
req.ifa.ifa_family = ip.Proto == 4 ? AF_INET : AF_INET6; req.ifa.ifa_family = ip.Proto == 4 ? AF_INET : AF_INET6;
req.ifa.ifa_prefixlen = ip.Mask; req.ifa.ifa_prefixlen = ip.Mask;
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;
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);
get_prefix(&lcl, ip.Address.c_str(), req.ifa.ifa_family);
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));
}); });