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 config from '../../../config'; | ||||||
| import DB from '../../../database'; | import DB from '../../../database'; | ||||||
| import logger from '../../../logger'; | import logger from '../../../logger'; | ||||||
|  | import * as IPCheck from '../../../utils/ipcheck.js'; | ||||||
| 
 | 
 | ||||||
| export async function $lookupNodeLocation(): Promise<void> { | export async function $lookupNodeLocation(): Promise<void> { | ||||||
|   let loggerTimer = new Date().getTime() / 1000; |   let loggerTimer = new Date().getTime() / 1000; | ||||||
| @ -27,6 +28,11 @@ export async function $lookupNodeLocation(): Promise<void> { | |||||||
|           const asn = lookupAsn.get(ip); |           const asn = lookupAsn.get(ip); | ||||||
|           const isp = lookupIsp.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)) { |           if (city && (asn || isp)) { | ||||||
|             const query = ` |             const query = ` | ||||||
|               UPDATE nodes SET  |               UPDATE nodes SET  | ||||||
| @ -41,7 +47,7 @@ export async function $lookupNodeLocation(): Promise<void> { | |||||||
|             `;
 |             `;
 | ||||||
| 
 | 
 | ||||||
|             const params = [ |             const params = [ | ||||||
|               isp?.autonomous_system_number ?? asn?.autonomous_system_number, |               asOverwrite ?? isp?.autonomous_system_number ?? asn?.autonomous_system_number, | ||||||
|               city.city?.geoname_id, |               city.city?.geoname_id, | ||||||
|               city.country?.geoname_id, |               city.country?.geoname_id, | ||||||
|               city.subdivisions ? city.subdivisions[0].geoname_id : null, |               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) { |             if (isp?.autonomous_system_organization ?? asn?.autonomous_system_organization) { | ||||||
|               await DB.query( |               await DB.query( | ||||||
|                 `INSERT IGNORE INTO geo_names (id, type, names) VALUES (?, 'as_organization', ?)`, |                 `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" |       "node_modules/@types" | ||||||
|     ], |     ], | ||||||
|     "allowSyntheticDefaultImports": true, |     "allowSyntheticDefaultImports": true, | ||||||
|     "esModuleInterop": true |     "esModuleInterop": true, | ||||||
|  |     "allowJs": true, | ||||||
|   }, |   }, | ||||||
|   "include": [ |   "include": [ | ||||||
|     "src/**/*.ts" |     "src/**/*.ts" | ||||||
|  | |||||||
| @ -99,7 +99,7 @@ do for url in / \ | |||||||
| 	'/api/v1/lightning/nodes/isp/39572' `# DataWeb` \ | 	'/api/v1/lightning/nodes/isp/39572' `# DataWeb` \ | ||||||
| 	'/api/v1/lightning/nodes/isp/14061' `# Digital Ocean` \ | 	'/api/v1/lightning/nodes/isp/14061' `# Digital Ocean` \ | ||||||
| 	'/api/v1/lightning/nodes/isp/24940,213230' `# Hetzner` \ | 	'/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/45102' `# Alibaba` \ | ||||||
| 	'/api/v1/lightning/nodes/isp/3209' `# Vodafone Germany` \ | 	'/api/v1/lightning/nodes/isp/3209' `# Vodafone Germany` \ | ||||||
| 	'/api/v1/lightning/nodes/isp/7922' `# Comcast Cable` \ | 	'/api/v1/lightning/nodes/isp/7922' `# Comcast Cable` \ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user