Files
vpn/set_endpoint.uc
2026-02-01 23:35:42 +01:00

153 lines
4.0 KiB
Ucode

#!/bin/ucode
import * as uloop from 'uloop';
import { readfile, popen, pipe } from 'fs';
//import { event_fns } from './set_endpoint_events.uc'
// Aggregate all Endpoints
// Start pipe and loop and listen for set_endpoint commands
// set_endpoint command structure: userId,endpoint
//
// The User fetches vendor endpoints over the vendors backend directly from the provider, if not possible if will be fetchable over our service
// If the User has a matching plan, the user can provide thier wireguard backend / socks proxy
function log(msg,code) {
let prefix = "[+] ";
if(code == 1) {
prefix = "[!W] ";
}
if(code == 2) {
prefix = "[!!!Err] ";
}
print(prefix + msg + "\n");
}
function endpoint_format(ip,port) {
return {
endpoint: {
ip: ip,
port: port
}
};
}
function tunnel_ip_format(v4_addr, v6_addr, v4_endpoint, v6_endpoint) {
return {
tunnel: {
ipv4: {
if_addr: v4_addr,
endpoint: v4_endpoint
},
ipv6: {
if_addr: v6_addr,
endpoint: v6_endpoint
}
}
};
}
function wireguard_format(name, pubkey, private_key_path, tunnel_props) {
return {
wireguard: {
name: name,
tunnel: tunnel_props,
public_key: pubkey,
private_key: private_key_path
}
};
}
function socks5_format() {}
function nm_unified_format(provider, data) {
return {
nm_unified: {
provider: provider,
data: data // Should be array of wireguard or openvpn or socks format
}
};
}
function wireguard_connect(ctx,args) {
}
// Converts mullvad endpoints respecting its config to nm wireguard endpoint obj
function mullvad_parse() {
const conf = json(readfile("/etc/providers/config_"+provider_name+".json"));
let raw_apiresp = readfile('/tmp/mullvad_endpoints');
let wg_part = {};
log(raw_apiresp);
if(raw_apiresp == null) {
status = system('uclient-fetch -q -O /tmp/mullvad_endpoints https://api.mullvad.net/app/v1/relays');
log("uclient-fetch error",2);
raw_apiresp = readfile('/tmp/mullvad_endpoints');
}
const parsed_resp = json(raw_apiresp);
log("Loading... mullvad");
log(parsed_resp);
wg_part = parsed_resp['wireguard'];
const port = 51820;
let data = [];
let i = 0;
MAX_ENDPOINT_COUNT = 5;
OFFSET = 0;
for (relay in wg_part['relays']) {
if(i > MAX_ENDPOINT_COUNT || i < OFFSET) {
break;
}
log("Creating endpoint obj for " + relay);
e_v4 = endpoint_format(relay['ipv4_addr_in'],port);
e_v6 = endpoint_format(relay['ipv6_addr_in'],port);
// Create Mullvad tunnel, getting its internal ip address from the config files (should be set to a database later)
tunnel = tunnel_ip_format(conf.ipv4, conf.ipv6, e_v4, e_v6);
log("Created Endpoint -> "+ e_v4 + "\n" + e_v6 + "\n"+ tunnel);
print(tunnel);
push(data, wireguard_format(relay['hostname'], relay['public_key'], config.private_key_path, tunnel));
i += 1;
}
return nm_unified_format('mullvad',content);
}
// An array first containing the mullvad_endpoints and then a timestamp of the current time
// Used to calculate if the endpoints are old
mullvad_endpoints = [mullvad_parse(),time()];
const mainPipeHandle = pipe();
let uloop = uloop.init();
if(!uloop) {
log("Error initiating uloop, exiting ...", 2);
exit(1);
}
let p = pipe();
// 1. Read sessionID,CommandID. After reading the initation state is started. CommandID can be resolved to its CommandObject and the pre function can be executed
// 2. Read sessionID,commaseperatedvalues after the initation state and the pre function got executed the objects parameters can be populated for the after function
// 3. Read sessionID,OpendedCommandID. If the Command initation state was opened for that sessionID execute the apply function using the parameters from step 2 as parameters and then execute the post function
let i = 0;
log("+++ Creating uloop handle using fd: ");
const handle = uloop.handle(p[1],(e) => {
if(e & uloop.ULOOP_WRITE)
log("Write event " + p[0].read(128));
},uloop.ULOOP_READ);
log("Created Handle for Event Messages - Event Handle:\n" + handle.fileno());
uloop.run();