Big code refactoring #10
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -3,8 +3,9 @@
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/node_modules/node-addon-api",
|
||||
"/usr/local/include/node",
|
||||
"/usr/local/lib/zig//libc/include/any-linux-any",
|
||||
"${workspaceFolder}/node_modules/node-addon-api",
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/addon"
|
||||
],
|
||||
|
@ -17,7 +17,7 @@ extern "C" {
|
||||
#include <netinet/in.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <malloc.h>
|
||||
// #include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
@ -74,9 +74,9 @@ void WireguardConfig::getWireguardConfig() {
|
||||
else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist");
|
||||
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 (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(devConfig->private_key);
|
||||
if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) publicKey = wgKeys::toString(devConfig->public_key);
|
||||
if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) portListen = devConfig->listen_port;
|
||||
if (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) this->privateKey = wgKeys::toString(devConfig->private_key);
|
||||
if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) this->publicKey = wgKeys::toString(devConfig->public_key);
|
||||
if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) this->portListen = devConfig->listen_port;
|
||||
this->interfaceAddress.GetInInterface(this->name);
|
||||
|
||||
for ((peer) = (devConfig)->first_peer; (peer); (peer) = (peer)->next_peer) {
|
||||
@ -291,48 +291,28 @@ typedef struct {
|
||||
__u32 data[8];
|
||||
} inet_prefix;
|
||||
|
||||
|
||||
// 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;
|
||||
memset(rth, 0, sizeof(rth));
|
||||
|
||||
// Creating the netlink socket of family NETLINK_ROUTE
|
||||
|
||||
rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (rth->fd < 0)
|
||||
{
|
||||
perror("cannot open netlink socket");
|
||||
return -1;
|
||||
}
|
||||
if (rth->fd < 0) throw std::string("cannot open netlink socket");
|
||||
memset(&rth->local, 0, sizeof(rth->local));
|
||||
rth->local.nl_family = AF_NETLINK;
|
||||
rth->local.nl_groups = 0;
|
||||
|
||||
// Binding the netlink socket
|
||||
if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0)
|
||||
{
|
||||
perror("cannot bind netlink socket");
|
||||
return -1;
|
||||
}
|
||||
if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) throw std::string("cannot bind netlink socket");
|
||||
|
||||
addr_len = sizeof(rth->local);
|
||||
if (getsockname(rth->fd, (struct sockaddr*)&rth->local, (socklen_t*) &addr_len) < 0)
|
||||
{
|
||||
perror("cannot getsockname");
|
||||
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;
|
||||
}
|
||||
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));
|
||||
if (rth->local.nl_family != AF_NETLINK) throw std::string("wrong address family").append(std::to_string(rth->local.nl_family));
|
||||
|
||||
rth->seq = time(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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_groups = groups;
|
||||
n->nlmsg_seq = ++rtnl->seq;
|
||||
if (answer == NULL)
|
||||
n->nlmsg_flags |= NLM_F_ACK;
|
||||
if (answer == NULL) n->nlmsg_flags |= NLM_F_ACK;
|
||||
// Actual sending of the message, status contains success/failure
|
||||
status = sendmsg(rtnl->fd, &msg, 0);
|
||||
if (status < 0)
|
||||
return -1;
|
||||
return sendmsg(rtnl->fd, &msg, 0);
|
||||
// if (status < 0) return -1;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
if (this->size() == 0) return;
|
||||
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));
|
||||
|
||||
ifa_index = devConfig->ifindex;
|
||||
free(devConfig);
|
||||
|
||||
struct rtnl_handle * rth;
|
||||
rth = (rtnl_handle*)malloc(sizeof(rtnl_handle));
|
||||
netlink_open(rth);
|
||||
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;
|
||||
|
||||
// structure of the netlink packet.
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ifaddrmsg ifa;
|
||||
char buf[1024];
|
||||
struct nlmsghdr n;
|
||||
struct ifaddrmsg ifa;
|
||||
char buf[1024];
|
||||
} 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_prefixlen = ip.Mask;
|
||||
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;
|
||||
|
||||
struct in_addr inAddr;
|
||||
inet_pton(req.ifa.ifa_family, ip.Address.c_str(), (void*)&inAddr);
|
||||
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!");
|
||||
addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
|
||||
if ((err = rtnl_talk(rth, &req.n, 0, 0, NULL)) < 0) throw std::string("Cannot set interface IP, code: ").append(std::to_string(err));
|
||||
}
|
||||
}
|
@ -155,9 +155,9 @@ class GetConfig : public WireguardConfig, public Promised {
|
||||
if (config.keepInterval >= 0) peerConfig.Set("keepInterval", config.keepInterval);
|
||||
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("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);
|
||||
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 */
|
||||
driveVersion?: string;
|
||||
deleteInterface(name: string): Promise<GetConfig>;
|
||||
deleteInterface(name: string): Promise<void>;
|
||||
listDevices(): Promise<string[]>;
|
||||
getConfig(name: string): Promise<GetConfig>;
|
||||
setConfig(config: SetConfig): Promise<void>;
|
||||
|
@ -23,7 +23,20 @@ await test("Wireguard interface", async t => {
|
||||
]
|
||||
};
|
||||
|
||||
await Kernel.setConfig(config);
|
||||
console.dir(await Kernel.getConfig(config.name), { depth: null });
|
||||
await Kernel.deleteInterface(config.name);
|
||||
const peer2 = await privateKey();
|
||||
config.peers[publicKey(peer2)] = {
|
||||
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