MWSE/Source/module/IPAllocation.js

224 lines
4.4 KiB
JavaScript

const knex = require("knex");
const { IPALLOCATION_DB } = require("../config");
const crypto = require("node:crypto");
const moment = require("moment");
let IPDB = knex({
client: "sqlite3",
connection: exports.IPALLOCATION_STORE_TYPE == "memory" ? ":memory:" : IPALLOCATION_DB,
useNullAsDefault: true
});
let flovitNumber = [
[
8,
12,
24,
48,
52,
56
],
[
7,
10,
13,
16,
19,
22,
25,
28,
31,
34,
37,
40,
43,
46,
49,
52,
55,
58,
61,
64,
67,
70,
73,
76,
79,
82
]
];
async function read(filter)
{
return await IPDB.table("iptable").where(filter).first();
}
async function has(filter)
{
return (
await IPDB.table("iptable").where(filter).count('* as key').first()
).key != 0;
}
async function flushAll()
{
await IPDB.table("iptable").delete();
}
async function write(value,filter)
{
await IPDB.table("iptable").where(filter).update(value);
}
async function create(value)
{
await IPDB.table("iptable").insert(value);
}
async function remove(...filterArgs)
{
await IPDB.table("iptable").where(...filterArgs).delete();
}
async function migrate()
{
if(!await IPDB.schema.hasTable("iptable"))
{
await IPDB.schema.createTable("iptable",function(table){
table.bigInteger("ipaddress").unsigned().primary();
table.text("owner").unique();
table.string("type", 50).defaultTo("client");
table.dateTime("created").defaultTo(IPDB.fn.now());
});
}
};
function iptobin(a,b,c,d)
{
const bin =
((a | 0) << 24) |
((b | 0) << 16) |
((c | 0) << 8) |
(d | 0);
return bin;
}
function bintoip(bin)
{
if(typeof bin == "string")
{
bin = bin | 0;
}
const octet1 = (bin >>> 24) & 0xff;
const octet2 = (bin >>> 16) & 0xff;
const octet3 = (bin >>> 8) & 0xff;
const octet4 = bin & 0xff;
return [octet1,octet2,octet3,octet4];
}
function randomMaskINIT()
{
if(typeof bin == "string")
{
bin = bin.split('.').map(e => e | 0);
}
let globalmask = crypto.randomInt(flovitNumber[0].length);
let macromask = crypto.randomInt(flovitNumber[1].length);
return [
flovitNumber[0][globalmask],
flovitNumber[1][macromask],
0,
0
]
}
async function init()
{
await migrate();
await flushAll();
await create({
ipaddress: 0, // globalmask & macromask
owner: randomMaskINIT().join('.'),
type: "system",
created: moment().format()
});
hook()
}
init.inited = false;
async function getip(owner, type)
{
let call = await read({
owner,
type
});
return !call ? false : {
ipaddress: call.ipaddress,
date: call.created
};
}
async function setip(owner, type, ip)
{
await getip(owner, type) ?
await write({
ipaddress: ip
},{
owner,
type
})
:
await create({
ipaddress: ip,
owner,
type
});
}
async function allocateIP(owner, type, changeOverlord)
{
let [a,b,c,d] = [ ,,, ];
if(changeOverlord)
{
[a,b,c,d] = randomMaskINIT();
}else{
let ipinfo = await read({
ipaddress: 0,
type: "system"
});
[a,b,c,d] = ipinfo.owner.split('.').map(e => e | 0);
}
while(1)
{
if(d != 255)
{
d++;
}else if(c != 255){
c++;
}else if(b != 255){
b++;
}else if(a != 255){
a++;
}else{
[a,b,c,d] = randomMaskINIT();
}
let query = {
ipaddress: iptobin(a,b,c,d)
};
let result = await has(query);
if(result == false)
{
await create({
ipaddress: iptobin(a,b,c,d),
owner,
type
});
await write({
owner: [a,b,c,d].join('.')
},{
type: "system",
ipaddress: 0
});
break;
}else{
console.log("Checking",[a,b,c,d].join('.'))
}
}
return[a,b,c,d].join('.')
}
process.nextTick(init);