Merge pull request #2441 from mempool/nymkappa/feature/ip-check
Fix wrong ASN for Lunanode ip ranges
This commit is contained in:
		
						commit
						af805f15c7
					
				@ -4,6 +4,7 @@ import nodesApi from '../../../api/explorer/nodes.api';
 | 
			
		||||
import config from '../../../config';
 | 
			
		||||
import DB from '../../../database';
 | 
			
		||||
import logger from '../../../logger';
 | 
			
		||||
import * as IPCheck from '../../../utils/ipcheck.js';
 | 
			
		||||
 | 
			
		||||
export async function $lookupNodeLocation(): Promise<void> {
 | 
			
		||||
  let loggerTimer = new Date().getTime() / 1000;
 | 
			
		||||
@ -27,6 +28,11 @@ export async function $lookupNodeLocation(): Promise<void> {
 | 
			
		||||
          const asn = lookupAsn.get(ip);
 | 
			
		||||
          const isp = lookupIsp.get(ip);
 | 
			
		||||
 | 
			
		||||
          let asOverwrite: number | null = null;
 | 
			
		||||
          if (asn && (IPCheck.match(ip, '170.75.160.0/20') || IPCheck.match(ip, '172.81.176.0/21'))) {
 | 
			
		||||
            asOverwrite = 394745;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (city && (asn || isp)) {
 | 
			
		||||
            const query = `
 | 
			
		||||
              UPDATE nodes SET 
 | 
			
		||||
@ -41,7 +47,7 @@ export async function $lookupNodeLocation(): Promise<void> {
 | 
			
		||||
            `;
 | 
			
		||||
 | 
			
		||||
            const params = [
 | 
			
		||||
              isp?.autonomous_system_number ?? asn?.autonomous_system_number,
 | 
			
		||||
              asOverwrite ?? isp?.autonomous_system_number ?? asn?.autonomous_system_number,
 | 
			
		||||
              city.city?.geoname_id,
 | 
			
		||||
              city.country?.geoname_id,
 | 
			
		||||
              city.subdivisions ? city.subdivisions[0].geoname_id : null,
 | 
			
		||||
@ -91,7 +97,7 @@ export async function $lookupNodeLocation(): Promise<void> {
 | 
			
		||||
            if (isp?.autonomous_system_organization ?? asn?.autonomous_system_organization) {
 | 
			
		||||
              await DB.query(
 | 
			
		||||
                `INSERT IGNORE INTO geo_names (id, type, names) VALUES (?, 'as_organization', ?)`,
 | 
			
		||||
                [isp?.autonomous_system_number ?? asn?.autonomous_system_number, JSON.stringify(isp?.isp ?? asn?.autonomous_system_organization)]);
 | 
			
		||||
                [asOverwrite ?? isp?.autonomous_system_number ?? asn?.autonomous_system_number, JSON.stringify(isp?.isp ?? asn?.autonomous_system_organization)]);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								backend/src/utils/ipcheck.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								backend/src/utils/ipcheck.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
var net = require('net');
 | 
			
		||||
 | 
			
		||||
var IPCheck = module.exports = function(input) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if (!(self instanceof IPCheck)) {
 | 
			
		||||
    return new IPCheck(input);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  self.input = input;
 | 
			
		||||
  self.parse();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
IPCheck.prototype.parse = function() {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if (!self.input || typeof self.input !== 'string') return self.valid = false;
 | 
			
		||||
 | 
			
		||||
  var ip;
 | 
			
		||||
 | 
			
		||||
  var pos = self.input.lastIndexOf('/');
 | 
			
		||||
  if (pos !== -1) {
 | 
			
		||||
    ip = self.input.substring(0, pos);
 | 
			
		||||
    self.mask = +self.input.substring(pos + 1);
 | 
			
		||||
  } else {
 | 
			
		||||
    ip = self.input;
 | 
			
		||||
    self.mask = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  self.ipv = net.isIP(ip);
 | 
			
		||||
  self.valid = !!self.ipv && !isNaN(self.mask);
 | 
			
		||||
 | 
			
		||||
  if (!self.valid) return;
 | 
			
		||||
 | 
			
		||||
  // default mask = 32 for ipv4 and 128 for ipv6
 | 
			
		||||
  if (self.mask === null) self.mask = self.ipv === 4 ? 32 : 128;
 | 
			
		||||
 | 
			
		||||
  if (self.ipv === 4) {
 | 
			
		||||
    // difference between ipv4 and ipv6 masks
 | 
			
		||||
    self.mask += 96;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (self.mask < 0 || self.mask > 128) {
 | 
			
		||||
    self.valid = false;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  self.address = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
 | 
			
		||||
 | 
			
		||||
  if(self.ipv === 4){
 | 
			
		||||
    self.parseIPv4(ip);
 | 
			
		||||
  }else{
 | 
			
		||||
    self.parseIPv6(ip);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
IPCheck.prototype.parseIPv4 = function(ip) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // ipv4 addresses live under ::ffff:0:0
 | 
			
		||||
  self.address[10] = self.address[11] = 0xff;
 | 
			
		||||
 | 
			
		||||
  var octets = ip.split('.');
 | 
			
		||||
  for (var i = 0; i < 4; i++) {
 | 
			
		||||
    self.address[i + 12] = parseInt(octets[i], 10);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var V6_TRANSITIONAL = /:(\d+\.\d+\.\d+\.\d+)$/;
 | 
			
		||||
 | 
			
		||||
IPCheck.prototype.parseIPv6 = function(ip) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  var transitionalMatch = V6_TRANSITIONAL.exec(ip);
 | 
			
		||||
  if(transitionalMatch){
 | 
			
		||||
    self.parseIPv4(transitionalMatch[1]);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var bits = ip.split(':');
 | 
			
		||||
  if (bits.length < 8) {
 | 
			
		||||
    ip = ip.replace('::', Array(11 - bits.length).join(':'));
 | 
			
		||||
    bits = ip.split(':');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var j = 0;
 | 
			
		||||
  for (var i = 0; i < bits.length; i += 1) {
 | 
			
		||||
    var x = bits[i] ? parseInt(bits[i], 16) : 0;
 | 
			
		||||
    self.address[j++] = x >> 8;
 | 
			
		||||
    self.address[j++] = x & 0xff;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
IPCheck.prototype.match = function(cidr) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if (!(cidr instanceof IPCheck)) cidr = new IPCheck(cidr);
 | 
			
		||||
  if (!self.valid || !cidr.valid) return false;
 | 
			
		||||
 | 
			
		||||
  var mask = cidr.mask;
 | 
			
		||||
  var i = 0;
 | 
			
		||||
 | 
			
		||||
  while (mask >= 8) {
 | 
			
		||||
    if (self.address[i] !== cidr.address[i]) return false;
 | 
			
		||||
 | 
			
		||||
    i++;
 | 
			
		||||
    mask -= 8;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var shift = 8 - mask;
 | 
			
		||||
  return (self.address[i] >>> shift) === (cidr.address[i] >>> shift);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IPCheck.match = function(ip, cidr) {
 | 
			
		||||
  ip = ip instanceof IPCheck ? ip : new IPCheck(ip);
 | 
			
		||||
  return ip.match(cidr);
 | 
			
		||||
};
 | 
			
		||||
@ -13,7 +13,8 @@
 | 
			
		||||
      "node_modules/@types"
 | 
			
		||||
    ],
 | 
			
		||||
    "allowSyntheticDefaultImports": true,
 | 
			
		||||
    "esModuleInterop": true
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
  },
 | 
			
		||||
  "include": [
 | 
			
		||||
    "src/**/*.ts"
 | 
			
		||||
 | 
			
		||||
@ -99,7 +99,7 @@ do for url in / \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/39572' `# DataWeb` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/14061' `# Digital Ocean` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/24940,213230' `# Hetzner` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/174' `# LunaNode` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/394745' `# LunaNode` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/45102' `# Alibaba` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/3209' `# Vodafone Germany` \
 | 
			
		||||
	'/api/v1/lightning/nodes/isp/7922' `# Comcast Cable` \
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user