import net from "node:net"; import IpToAsn from "ip-to-asn"; import { getASFromCache, updateAS, isASBanned, incrementRejected, incrementAccepted, } from "./db.mjs"; const asClient = new IpToAsn(); // Create a server const server = net.createServer((socket) => { // console.log(`Policy server connection established`); socket.on("data", async (data) => { const lines = data.toString().trim(); let response = "dunno"; // Default response try { const command = lines.split(/[\r\n]/).reduce((acc, i) => { const [key, value] = i.split("="); return { ...acc, [key]: value }; }, {}); const { client_address, client_name, sender, recipient } = command; console.log( `Incoming email from "${client_name}[${client_address}]. ${sender} -> ${recipient}`, ); // check if IP belongs to previously cached AS records let as = getASFromCache(client_address); if (!as) { // console.log(`Fetching AS for ${client_address}`); const result = await query(client_address); if (result) { const { range, ASN, description } = result; as = ASN; updateAS(as, range, description); } } const reason = isASBanned(as); if (reason) { // console.log(`AS ${as} is banned`); response = `reject ${reason.reason}`; incrementRejected(as); } else { incrementAccepted(as); } // Check if AS is in the ban list } catch (err) { console.error("Error processing command:", err); } console.log(`Verdict: ${response}`); socket.write(`${response}\r\n`); }); socket.on("end", () => { console.log("Policy server connection ended"); }); socket.on("error", (err) => { console.error("Policy server socket error:", err); }); }); // Start the server server.listen(12346, "127.0.0.1", () => { console.log(`Policy server running`); }); function query(...ip) { return new Promise((resolve, reject) => { asClient.query(ip, (err, result) => { if (err) { return reject(err); } resolve(result[ip[0]]); }); }); }