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,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));
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user