build-cidr.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. const https = require('https');
  2. const { promises: fsPromises } = require('fs');
  3. const { resolve: pathResolve } = require('path');
  4. let cidrTools;
  5. try {
  6. cidrTools = require('cidr-tools');
  7. } catch (e) {
  8. console.log('Dependency "cidr-tools" not found');
  9. console.log('"npm i cidr-tools" then try again!');
  10. process.exit(1);
  11. }
  12. (async () => {
  13. const cidr = (await get('raw.githubusercontent.com', '/tmplink/IPDB/main/ipv4/cidr/CN.txt')).split('\n');
  14. let FILTER_FLAG = false;
  15. const filteredCidr = cidr.filter(Boolean).filter((ip, index) => {
  16. if (FILTER_FLAG) return false;
  17. const prev = cidr[index - 1];
  18. const next = cidr[index + 1];
  19. const prevA = Number(prev?.split('.')[0]);
  20. const nextA = Number(next?.split('.')[0]);
  21. if (
  22. prevA >= 223 // MCAST-TEST-NET
  23. && nextA < 10
  24. && prevA > nextA
  25. ) {
  26. FILTER_FLAG = true;
  27. return false;
  28. }
  29. return true;
  30. });
  31. const mergedCidr = cidrTools.merge(filteredCidr);
  32. if (mergedCidr.length < 4500) {
  33. console.log(`Merged routes (which is ${mergedCidr.length}) is less than 5000 routes, which can't be right. Aborted`);
  34. process.exit(1);
  35. }
  36. return fsPromises.writeFile(pathResolve(__dirname, '../List/ip/china_ip.conf'), makeCidrList(mergedCidr), { encoding: 'utf-8' });
  37. })();
  38. function makeCidrList(cidr) {
  39. const date = new Date();
  40. return `############################
  41. # Mainland China IPv4 CIDR
  42. # Data from vx.link (tmplink @ GitHub)
  43. # Last Updated: ${date.getFullYear()}-${date.getUTCMonth() + 1}-${date.getUTCDate()} ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()}
  44. # Routes: ${cidr.length}
  45. ############################\n` + cidr.map(i => `IP-CIDR,${i}`).join('\n') + '\n########### END ############\n';
  46. };
  47. function get(hostname, path) {
  48. return new Promise((resolve, reject) => {
  49. const req = https.request(
  50. {
  51. hostname,
  52. path,
  53. method: 'GET',
  54. },
  55. (res) => {
  56. const body = [];
  57. res.on('data', (chunk) => {
  58. body.push(chunk);
  59. });
  60. res.on('end', () => {
  61. try {
  62. resolve(String(Buffer.concat(body)));
  63. } catch (e) {
  64. reject(e);
  65. }
  66. });
  67. req.on('error', (err) => {
  68. reject(err);
  69. });
  70. }
  71. );
  72. req.end();
  73. });
  74. }