1'use strict'; 2 3const { 4 Boolean, 5 ObjectSetPrototypeOf, 6 Symbol, 7} = primordials; 8 9const { 10 BlockList: BlockListHandle, 11} = internalBinding('block_list'); 12 13const { 14 customInspectSymbol: kInspect, 15} = require('internal/util'); 16 17const { 18 SocketAddress, 19 kHandle: kSocketAddressHandle, 20} = require('internal/socketaddress'); 21 22const { 23 JSTransferable, 24 kClone, 25 kDeserialize, 26} = require('internal/worker/js_transferable'); 27 28const { inspect } = require('internal/util/inspect'); 29 30const kHandle = Symbol('kHandle'); 31const { owner_symbol } = internalBinding('symbols'); 32 33const { 34 ERR_INVALID_ARG_VALUE, 35} = require('internal/errors').codes; 36 37const { validateInt32, validateString } = require('internal/validators'); 38 39class BlockList extends JSTransferable { 40 constructor() { 41 super(); 42 this[kHandle] = new BlockListHandle(); 43 this[kHandle][owner_symbol] = this; 44 } 45 46 [kInspect](depth, options) { 47 if (depth < 0) 48 return this; 49 50 const opts = { 51 ...options, 52 depth: options.depth == null ? null : options.depth - 1, 53 }; 54 55 return `BlockList ${inspect({ 56 rules: this.rules, 57 }, opts)}`; 58 } 59 60 addAddress(address, family = 'ipv4') { 61 if (!SocketAddress.isSocketAddress(address)) { 62 validateString(address, 'address'); 63 validateString(family, 'family'); 64 address = new SocketAddress({ 65 address, 66 family, 67 }); 68 } 69 this[kHandle].addAddress(address[kSocketAddressHandle]); 70 } 71 72 addRange(start, end, family = 'ipv4') { 73 if (!SocketAddress.isSocketAddress(start)) { 74 validateString(start, 'start'); 75 validateString(family, 'family'); 76 start = new SocketAddress({ 77 address: start, 78 family, 79 }); 80 } 81 if (!SocketAddress.isSocketAddress(end)) { 82 validateString(end, 'end'); 83 validateString(family, 'family'); 84 end = new SocketAddress({ 85 address: end, 86 family, 87 }); 88 } 89 const ret = this[kHandle].addRange( 90 start[kSocketAddressHandle], 91 end[kSocketAddressHandle]); 92 if (ret === false) 93 throw new ERR_INVALID_ARG_VALUE('start', start, 'must come before end'); 94 } 95 96 addSubnet(network, prefix, family = 'ipv4') { 97 if (!SocketAddress.isSocketAddress(network)) { 98 validateString(network, 'network'); 99 validateString(family, 'family'); 100 network = new SocketAddress({ 101 address: network, 102 family, 103 }); 104 } 105 switch (network.family) { 106 case 'ipv4': 107 validateInt32(prefix, 'prefix', 0, 32); 108 break; 109 case 'ipv6': 110 validateInt32(prefix, 'prefix', 0, 128); 111 break; 112 } 113 this[kHandle].addSubnet(network[kSocketAddressHandle], prefix); 114 } 115 116 check(address, family = 'ipv4') { 117 if (!SocketAddress.isSocketAddress(address)) { 118 validateString(address, 'address'); 119 validateString(family, 'family'); 120 try { 121 address = new SocketAddress({ 122 address, 123 family, 124 }); 125 } catch { 126 // Ignore the error. If it's not a valid address, return false. 127 return false; 128 } 129 } 130 return Boolean(this[kHandle].check(address[kSocketAddressHandle])); 131 } 132 133 get rules() { 134 return this[kHandle].getRules(); 135 } 136 137 [kClone]() { 138 const handle = this[kHandle]; 139 return { 140 data: { handle }, 141 deserializeInfo: 'internal/blocklist:InternalBlockList', 142 }; 143 } 144 145 [kDeserialize]({ handle }) { 146 this[kHandle] = handle; 147 this[kHandle][owner_symbol] = this; 148 } 149} 150 151class InternalBlockList extends JSTransferable { 152 constructor(handle) { 153 super(); 154 this[kHandle] = handle; 155 if (handle !== undefined) 156 handle[owner_symbol] = this; 157 } 158} 159 160InternalBlockList.prototype.constructor = BlockList.prototype.constructor; 161ObjectSetPrototypeOf(InternalBlockList.prototype, BlockList.prototype); 162 163module.exports = { 164 BlockList, 165 InternalBlockList, 166}; 167