@mercuryworkshop/wisp-js
Advanced tools
Comparing version 0.2.2 to 0.3.0
@@ -1,1 +0,1 @@ | ||
var wisp_full;(()=>{var t={512:function(t){!function(e){"use strict";const s="(0?\\d+|0x[a-f0-9]+)",n={fourOctet:new RegExp(`^${s}\\.${s}\\.${s}\\.${s}$`,"i"),threeOctet:new RegExp(`^${s}\\.${s}\\.${s}$`,"i"),twoOctet:new RegExp(`^${s}\\.${s}$`,"i"),longValue:new RegExp(`^${s}$`,"i")},i=new RegExp("^0[0-7]+$","i"),r=new RegExp("^0x[a-f0-9]+$","i"),o="%[0-9a-z]{1,}",a="(?:[0-9a-f]+::?)+",c={zoneIndex:new RegExp(o,"i"),native:new RegExp(`^(::)?(${a})?([0-9a-f]+)?(::)?(${o})?$`,"i"),deprecatedTransitional:new RegExp(`^(?:::)(${s}\\.${s}\\.${s}\\.${s}(${o})?)$`,"i"),transitional:new RegExp(`^((?:${a})|(?:::)(?:${a})?)${s}\\.${s}\\.${s}\\.${s}(${o})?$`,"i")};function h(t,e){if(t.indexOf("::")!==t.lastIndexOf("::"))return null;let s,n,i=0,r=-1,o=(t.match(c.zoneIndex)||[])[0];for(o&&(o=o.substring(1),t=t.replace(/%.+$/,""));(r=t.indexOf(":",r+1))>=0;)i++;if("::"===t.substr(0,2)&&i--,"::"===t.substr(-2,2)&&i--,i>e)return null;for(n=e-i,s=":";n--;)s+="0:";return":"===(t=t.replace("::",s))[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),{parts:e=function(){const e=t.split(":"),s=[];for(let t=0;t<e.length;t++)s.push(parseInt(e[t],16));return s}(),zoneId:o}}function l(t,e,s,n){if(t.length!==e.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");let i,r=0;for(;n>0;){if(i=s-n,i<0&&(i=0),t[r]>>i!=e[r]>>i)return!1;n-=s,r+=1}return!0}function u(t){if(r.test(t))return parseInt(t,16);if("0"===t[0]&&!isNaN(parseInt(t[1],10))){if(i.test(t))return parseInt(t,8);throw new Error(`ipaddr: cannot parse ${t} as octal`)}return parseInt(t,10)}function p(t,e){for(;t.length<e;)t=`0${t}`;return t}const d={};d.IPv4=function(){function t(t){if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");let e,s;for(e=0;e<t.length;e++)if(s=t[e],!(0<=s&&s<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=t}return t.prototype.SpecialRanges={unspecified:[[new t([0,0,0,0]),8]],broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],carrierGradeNat:[[new t([100,64,0,0]),10]],private:[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,18,0,0]),15],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]],as112:[[new t([192,175,48,0]),24],[new t([192,31,196,0]),24]],amt:[[new t([192,52,193,0]),24]]},t.prototype.kind=function(){return"ipv4"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return l(this.octets,t.octets,8,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0};let n,i,r;for(n=3;n>=0;n-=1){if(i=this.octets[n],!(i in s))return null;if(r=s[i],e&&0!==r)return null;8!==r&&(e=!0),t+=r}return 32-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.toIPv4MappedAddress=function(){return d.IPv6.parse(`::ffff:${this.toString()}`)},t.prototype.toNormalizedString=function(){return this.toString()},t.prototype.toString=function(){return this.octets.join(".")},t}(),d.IPv4.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),n=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),i=[];let r=0;for(;r<4;)i.push(parseInt(s[r],10)|255^parseInt(n[r],10)),r++;return new this(i)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.isIPv4=function(t){return null!==this.parser(t)},d.IPv4.isValid=function(t){try{return new this(this.parser(t)),!0}catch(t){return!1}},d.IPv4.isValidCIDR=function(t){try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv4.isValidFourPartDecimal=function(t){return!(!d.IPv4.isValid(t)||!t.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/))},d.IPv4.networkAddressFromCIDR=function(t){let e,s,n,i,r;try{for(e=this.parseCIDR(t),n=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),i=[],s=0;s<4;)i.push(parseInt(n[s],10)&parseInt(r[s],10)),s++;return new this(i)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.parse=function(t){const e=this.parser(t);if(null===e)throw new Error("ipaddr: string is not formatted like an IPv4 Address");return new this(e)},d.IPv4.parseCIDR=function(t){let e;if(e=t.match(/^(.+)\/(\d+)$/)){const t=parseInt(e[2]);if(t>=0&&t<=32){const s=[this.parse(e[1]),t];return Object.defineProperty(s,"toString",{value:function(){return this.join("/")}}),s}}throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},d.IPv4.parser=function(t){let e,s,i;if(e=t.match(n.fourOctet))return function(){const t=e.slice(1,6),n=[];for(let e=0;e<t.length;e++)s=t[e],n.push(u(s));return n}();if(e=t.match(n.longValue)){if(i=u(e[1]),i>4294967295||i<0)throw new Error("ipaddr: address outside defined range");return function(){const t=[];let e;for(e=0;e<=24;e+=8)t.push(i>>e&255);return t}().reverse()}return(e=t.match(n.twoOctet))?function(){const t=e.slice(1,4),s=[];if(i=u(t[1]),i>16777215||i<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(i>>16&255),s.push(i>>8&255),s.push(255&i),s}():(e=t.match(n.threeOctet))?function(){const t=e.slice(1,5),s=[];if(i=u(t[2]),i>65535||i<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(u(t[1])),s.push(i>>8&255),s.push(255&i),s}():null},d.IPv4.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>32)throw new Error("ipaddr: invalid IPv4 prefix length");const e=[0,0,0,0];let s=0;const n=Math.floor(t/8);for(;s<n;)e[s]=255,s++;return n<4&&(e[n]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.IPv6=function(){function t(t,e){let s,n;if(16===t.length)for(this.parts=[],s=0;s<=14;s+=2)this.parts.push(t[s]<<8|t[s+1]);else{if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=t}for(s=0;s<this.parts.length;s++)if(n=this.parts[s],!(0<=n&&n<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits");e&&(this.zoneId=e)}return t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],discard:[new t([256,0,0,0,0,0,0,0]),64],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],benchmarking:[new t([8193,2,0,0,0,0,0,0]),48],amt:[new t([8193,3,0,0,0,0,0,0]),32],as112v6:[[new t([8193,4,274,0,0,0,0,0]),48],[new t([9760,79,32768,0,0,0,0,0]),48]],deprecated:[new t([8193,16,0,0,0,0,0,0]),28],orchid2:[new t([8193,32,0,0,0,0,0,0]),28],droneRemoteIdProtocolEntityTags:[new t([8193,48,0,0,0,0,0,0]),28],reserved:[[new t([8193,0,0,0,0,0,0,0]),23],[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.kind=function(){return"ipv6"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return l(this.parts,t.parts,16,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:16,32768:15,49152:14,57344:13,61440:12,63488:11,64512:10,65024:9,65280:8,65408:7,65472:6,65504:5,65520:4,65528:3,65532:2,65534:1,65535:0};let n,i;for(let r=7;r>=0;r-=1){if(n=this.parts[r],!(n in s))return null;if(i=s[n],e&&0!==i)return null;16!==i&&(e=!0),t+=i}return 128-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){let t;const e=[],s=this.parts;for(let n=0;n<s.length;n++)t=s[n],e.push(t>>8),e.push(255&t);return e},t.prototype.toFixedLengthString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(p(this.parts[e].toString(16),4));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toIPv4Address=function(){if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");const t=this.parts.slice(-2),e=t[0],s=t[1];return new d.IPv4([e>>8,255&e,s>>8,255&s])},t.prototype.toNormalizedString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(this.parts[e].toString(16));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toRFC5952String=function(){const t=/((^|:)(0(:|$)){2,})/g,e=this.toNormalizedString();let s,n=0,i=-1;for(;s=t.exec(e);)s[0].length>i&&(n=s.index,i=s[0].length);return i<0?e:`${e.substring(0,n)}::${e.substring(n+i)}`},t.prototype.toString=function(){return this.toRFC5952String()},t}(),d.IPv6.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),n=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),i=[];let r=0;for(;r<16;)i.push(parseInt(s[r],10)|255^parseInt(n[r],10)),r++;return new this(i)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.isIPv6=function(t){return null!==this.parser(t)},d.IPv6.isValid=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{const e=this.parser(t);return new this(e.parts,e.zoneId),!0}catch(t){return!1}},d.IPv6.isValidCIDR=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv6.networkAddressFromCIDR=function(t){let e,s,n,i,r;try{for(e=this.parseCIDR(t),n=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),i=[],s=0;s<16;)i.push(parseInt(n[s],10)&parseInt(r[s],10)),s++;return new this(i)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.parse=function(t){const e=this.parser(t);if(null===e.parts)throw new Error("ipaddr: string is not formatted like an IPv6 Address");return new this(e.parts,e.zoneId)},d.IPv6.parseCIDR=function(t){let e,s,n;if((s=t.match(/^(.+)\/(\d+)$/))&&(e=parseInt(s[2]),e>=0&&e<=128))return n=[this.parse(s[1]),e],Object.defineProperty(n,"toString",{value:function(){return this.join("/")}}),n;throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},d.IPv6.parser=function(t){let e,s,n,i,r,o;if(n=t.match(c.deprecatedTransitional))return this.parser(`::ffff:${n[1]}`);if(c.native.test(t))return h(t,8);if((n=t.match(c.transitional))&&(o=n[6]||"",e=n[1],n[1].endsWith("::")||(e=e.slice(0,-1)),e=h(e+o,6),e.parts)){for(r=[parseInt(n[2]),parseInt(n[3]),parseInt(n[4]),parseInt(n[5])],s=0;s<r.length;s++)if(i=r[s],!(0<=i&&i<=255))return null;return e.parts.push(r[0]<<8|r[1]),e.parts.push(r[2]<<8|r[3]),{parts:e.parts,zoneId:e.zoneId}}return null},d.IPv6.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>128)throw new Error("ipaddr: invalid IPv6 prefix length");const e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];let s=0;const n=Math.floor(t/8);for(;s<n;)e[s]=255,s++;return n<16&&(e[n]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.fromByteArray=function(t){const e=t.length;if(4===e)return new d.IPv4(t);if(16===e)return new d.IPv6(t);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},d.isValid=function(t){return d.IPv6.isValid(t)||d.IPv4.isValid(t)},d.isValidCIDR=function(t){return d.IPv6.isValidCIDR(t)||d.IPv4.isValidCIDR(t)},d.parse=function(t){if(d.IPv6.isValid(t))return d.IPv6.parse(t);if(d.IPv4.isValid(t))return d.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},d.parseCIDR=function(t){try{return d.IPv6.parseCIDR(t)}catch(e){try{return d.IPv4.parseCIDR(t)}catch(t){throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},d.process=function(t){const e=this.parse(t);return"ipv6"===e.kind()&&e.isIPv4MappedAddress()?e.toIPv4Address():e},d.subnetMatch=function(t,e,s){let n,i,r,o;for(i in null==s&&(s="unicast"),e)if(Object.prototype.hasOwnProperty.call(e,i))for(r=e[i],!r[0]||r[0]instanceof Array||(r=[r]),n=0;n<r.length;n++)if(o=r[n],t.kind()===o[0].kind()&&t.match.apply(t,o))return i;return s},t.exports?t.exports=d:e.ipaddr=d}(this)}},e={};function s(n){var i=e[n];if(void 0!==i)return i.exports;var r=e[n]={exports:{}};return t[n].call(r.exports,r,r.exports,s),r.exports}s.d=(t,e)=>{for(var n in e)s.o(e,n)&&!s.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};(()=>{"use strict";s.r(n),s.d(n,{client:()=>e,packet:()=>t,server:()=>i});var t={};s.r(t),s.d(t,{ClosePayload:()=>v,ConnectPayload:()=>_,ContinuePayload:()=>m,DataPayload:()=>y,WispBuffer:()=>f,WispPacket:()=>w,close_reasons:()=>I,packet_classes:()=>g,packet_types:()=>b,stream_types:()=>k});var e={};s.r(e),s.d(e,{ClientConnection:()=>$,WispWebSocket:()=>z,_wisp_connections:()=>E});var i={};s.r(i),s.d(i,{ServerConnection:()=>tt,ServerStream:()=>Z,options:()=>U,routeRequest:()=>nt});const r=globalThis.WebSocket,o=globalThis.crypto,a=null,c=null,h=null,l=new TextEncoder,u=l.encode.bind(l),p=new TextDecoder,d=p.decode.bind(p);class f{constructor(t){if(t instanceof Uint8Array)this.from_array(t);else if("number"==typeof t)this.from_array(new Uint8Array(t));else{if("string"!=typeof t)throw console.trace(),"invalid data type passed to wisp buffer constructor";this.from_array(u(t))}}from_array(t){this.size=t.length,this.bytes=t,this.view=new DataView(t.buffer)}concat(t){let e=new f(this.size+t.size);return e.bytes.set(this.bytes,0),e.bytes.set(t.bytes,this.size),e}slice(t,e){let s=this.bytes.slice(t,e);return new f(s)}}class w{static min_size=5;constructor({type:t,stream_id:e,payload:s,payload_bytes:n}){this.type=t,this.stream_id=e,this.payload_bytes=n,this.payload=s}static parse(t){return new w({type:t.view.getUint8(0),stream_id:t.view.getUint32(1,!0),payload_bytes:t.slice(5)})}static parse_all(t){if(t.size<w.min_size)throw"packet too small";let e=w.parse(t),s=g[e.type];if(void 0===s)throw"invalid packet type";if(e.payload_bytes.size<s.size)throw"payload too small";return e.payload=s.parse(e.payload_bytes),e}serialize(){let t=new f(5);return t.view.setUint8(0,this.type),t.view.setUint32(1,this.stream_id,!0),t=t.concat(this.payload.serialize()),t}}class _{static min_size=3;static type=1;static name="CONNECT";constructor({stream_type:t,port:e,hostname:s}){this.stream_type=t,this.port=e,this.hostname=s}static parse(t){return new _({stream_type:t.view.getUint8(0),port:t.view.getUint16(1,!0),hostname:d(t.slice(3).bytes)})}serialize(){let t=new f(3);return t.view.setUint8(0,this.stream_type),t.view.setUint16(1,this.port,!0),t=t.concat(new f(this.hostname)),t}}class y{static min_size=0;static type=2;static name="DATA";constructor({data:t}){this.data=t}static parse(t){return new y({data:t})}serialize(){return this.data}}class m{static type=3;static name="CONTINUE";constructor({buffer_remaining:t}){this.buffer_remaining=t}static parse(t){return new m({buffer_remaining:t.view.getUint32(0,!0)})}serialize(){let t=new f(4);return t.view.setUint32(0,this.buffer_remaining,!0),t}}class v{static min_size=1;static type=4;static name="CLOSE";constructor({reason:t}){this.reason=t}static parse(t){return new v({reason:t.view.getUint8(0)})}serialize(){let t=new f(1);return t.view.setUint8(0,this.buffer_remaining),t}}const g=[void 0,_,y,m,v],b={CONNECT:1,DATA:2,CONTINUE:3,CLOSE:4},k={TCP:1,UDP:2},I={Unknown:1,Voluntary:2,NetworkError:3,InvalidInfo:65,UnreachableHost:66,NoResponse:67,ConnRefused:68,TransferTimeout:71,HostBlocked:72,ConnThrottled:73,ClientError:129};class P{constructor(t,e,s,n,i,r,o){this.hostname=t,this.port=e,this.ws=s,this.buffer_size=n,this.stream_id=i,this.connection=r,this.stream_type=o,this.send_buffer=[],this.open=!0,this.onopen=()=>{},this.onclose=()=>{},this.onmessage=()=>{}}send(t){if(this.buffer_size>0||!this.open||this.stream_type===k.UDP){let e=new w({type:b.DATA,stream_id:this.stream_id,payload:new y({data:new f(t)})});this.ws.send(e.serialize().bytes),this.buffer_size--}else this.send_buffer.push(t)}continue_received(t){for(this.buffer_size=t;this.buffer_size>0&&this.send_buffer.length>0;)this.send(this.send_buffer.shift())}close(t=1){if(!this.open)return;let e=new w({type:b.CLOSE,stream_id,payload:new v({reason:t})});this.ws.send(e.serialize().bytes),this.open=!1,delete this.connection.active_streams[this.stream_id]}}class ${constructor(t){if(!t.endsWith("/"))throw"wisp endpoints must end with a trailing forward slash";this.wisp_url=t,this.max_buffer_size=null,this.active_streams={},this.connected=!1,this.connecting=!1,this.next_stream_id=1,this.onopen=()=>{},this.onclose=()=>{},this.onerror=()=>{},this.onmessage=()=>{},this.connect_ws()}connect_ws(){this.ws=new r(this.wisp_url),this.ws.binaryType="arraybuffer",this.connecting=!0,this.ws.onerror=()=>{this.on_ws_close(),this.onerror()},this.ws.onclose=()=>{this.on_ws_close(),this.onclose()},this.ws.onmessage=t=>{this.on_ws_msg(t),this.connecting&&(this.connected=!0,this.connecting=!1,this.onopen())}}close_stream(t,e){t.onclose(e),delete this.active_streams[t.stream_id]}on_ws_close(){this.connected=!1,this.connecting=!1;for(let t of Object.keys(this.active_streams))this.close_stream(this.active_streams[t],3)}create_stream(t,e,s="tcp"){let n="udp"===s?2:1,i=this.next_stream_id++,r=new P(t,e,this.ws,this.max_buffer_size,i,this,n);this.active_streams[i]=r,r.open=this.connected;let o=new w({type:b.CONNECT,stream_id:i,payload:new _({stream_type:n,port:e,hostname:t})});return this.ws.send(o.serialize().bytes),r}on_ws_msg(t){let e=new f(new Uint8Array(t.data));if(e.size<w.min_size)return void console.warn("wisp client warning: received a packet which is too short");let s=w.parse_all(e),n=this.active_streams[s.stream_id];void 0!==n||0===s.stream_id&&s.type===b.CONTINUE?s.type===b.DATA?n.onmessage(s.payload_bytes.bytes):s.type===b.CONTINUE&&0==s.stream_id?this.max_buffer_size=s.payload.buffer_remaining:s.type===b.CONTINUE?n.continue_received(s.payload.buffer_size):s.type===b.CLOSE?this.close_stream(n,s.payload.reason):console.warn(`wisp client warning: receive an invalid packet of type ${s.type}`):console.warn(`wisp client warning: received a ${g[s.type].name} packet for a stream which doesn't exist`)}}const C=globalThis.CloseEvent||Event,E={};class z extends EventTarget{constructor(t,e){super(),this.url=t,this.protocols=e,this.binaryType="blob",this.stream=null,this.connection=null,this.onopen=()=>{},this.onerror=()=>{},this.onmessage=()=>{},this.onclose=()=>{},this.CONNECTING=0,this.OPEN=1,this.CLOSING=2,this.CLOSED=3,this._ready_state=this.CONNECTING;let s=this.url.split("/"),n=s.pop().split(":");this.host=n[0],this.port=parseInt(n[1]),this.real_url=s.join("/")+"/",this.init_connection()}on_conn_close(){this._ready_state=this.CLOSED,E[this.real_url]&&(this.onerror(new Event("error")),this.dispatchEvent(new Event("error"))),delete E[this.real_url]}init_connection(){if(this.connection=E[this.real_url],this.connection)if(this.connection.connected)this.connection=E[this.real_url],this.init_stream();else{let t=this.connection.onopen;this.connection.onopen=()=>{t(),this.init_stream()}}else this.connection=new $(this.real_url),this.connection.onopen=()=>{this.init_stream()},this.connection.onclose=()=>{this.on_conn_close()},this.connection.onerror=()=>{this.on_conn_close()},E[this.real_url]=this.connection}init_stream(){this._ready_state=this.OPEN,this.stream=this.connection.create_stream(this.host,this.port),this.stream.onmessage=t=>{let e;if("blob"==this.binaryType)e=new Blob(t);else{if("arraybuffer"!=this.binaryType)throw"invalid binaryType string";e=t.buffer}let s=new MessageEvent("message",{data:e});this.onmessage(s),this.dispatchEvent(s)},this.stream.onclose=t=>{this._ready_state=this.CLOSED;let e=new C("close",{code:t});this.onclose(e),this.dispatchEvent(e)};let t=new Event("open");this.onopen(t),this.dispatchEvent(t)}send(t){let e;if(t instanceof Uint8Array)e=t;else if("string"==typeof t)e=(new TextEncoder).encode(t);else{if(t instanceof Blob)return void t.arrayBuffer().then((t=>{this.send(t)}));if(t instanceof ArrayBuffer)e=new Uint8Array(t);else{if(!ArrayBuffer.isView(t))throw"invalid data type to be sent";e=new Uint8Array(t.buffer)}}if(!this.stream)throw"websocket is not ready";this.stream.send(e)}close(){this.stream.close(2)}get bufferedAmount(){let t=0;for(let e of this.stream.send_buffer)t+=e.length;return t}get extensions(){return""}get protocol(){return"binary"}get readyState(){return this._ready_state}}const x=1,D=2,S=3;let A=x;function R(){let[t,e]=(new Date).toJSON().split("T");return t=t.replaceAll("-","/"),e=e.split(".")[0],`[${t} - ${e}]`}function T(...t){A>x||console.info(R()+" info:",...t)}function O(...t){A>D||console.warn(R()+" warn:",...t)}function N(...t){A>S||console.error(R()+" error:",...t)}const U={hostname_blacklist:null,hostname_whitelist:null,port_blacklist:null,port_whitelist:null,allow_direct_ip:!0,allow_private_ips:!1,allow_loopback_ips:!1,client_ip_blacklist:null,client_ip_whitelist:null,stream_limit_per_host:-1,stream_limit_total:-1,allow_udp_streams:!0,allow_tcp_streams:!0,dns_ttl:120};class B{send_buffer_size=33554432;constructor(t){this.ws=t,this.connected=!1,this.data_queue=new M(1)}async connect(){await new Promise(((t,e)=>{this.ws.onopen=()=>{this.connected=!0,t()},this.ws.onmessage=t=>{this.data_queue.put(t.data)},this.ws.onclose=()=>{this.connected?this.data_queue.close():e()},this.ws.readyState===this.ws.OPEN&&(this.connected=!0,t())}))}async recv(){return await this.data_queue.get()}async send(t){if(this.ws.send(t),!(this.ws.bufferedAmount<=this.send_buffer_size))for(;!(this.ws.bufferedAmount<=this.send_buffer_size/2);)await new Promise((t=>{setTimeout(t,10)}))}close(t,e){this.ws.close(t,e),this.data_queue.close()}get buffered_amount(){return this.ws.bufferedAmount}}class M{constructor(t){this.max_size=t,this.queue=[],this.put_callbacks=[],this.get_callbacks=[]}put_now(t){this.queue.push(t),this.get_callbacks.shift()?.()}async put(t){this.size<=this.max_size||await new Promise((t=>{this.put_callbacks.push(t)})),this.put_now(t)}get_now(){return this.put_callbacks.shift()?.(),this.queue.shift()}async get(){return this.size>0||await new Promise((t=>{this.get_callbacks.push(t)})),this.get_now()}close(){let t;for(this.queue=[];t=this.get_callbacks.shift();)t();for(;t=this.put_callbacks.shift();)t()}get size(){return this.queue.length}}const q="undefined"!=typeof process,V=new Map;function L(){if(!q)throw"not running on node.js"}async function j(t){if(!q)return t;let e=a.isIP(t);if(4===e||6===e)return t;let s=Date.now();for(let[t,e]of V)s-e.time>U.dns_ttl&&V.delete(t);let n,i=V.get(t);if(i){if(i.error)throw i.error;return i.address}try{n=(await c.lookup(t)).address,V.set(t,{time:Date.now(),address:n})}catch(e){throw V.set(t,{time:Date.now(),error:e}),e}return n}class F{constructor(t,e){L(),this.hostname=t,this.port=e,this.recv_buffer_size=128,this.socket=null,this.paused=!1,this.connected=!1,this.data_queue=new M(this.recv_buffer_size)}async connect(){let t=await j(this.hostname);await new Promise(((e,s)=>{this.socket=new a.Socket,this.socket.setNoDelay(!0),this.socket.on("connect",(()=>{this.connected=!0,e()})),this.socket.on("data",(t=>{this.data_queue.put(t)})),this.socket.on("close",(t=>{t&&!this.connected?s():this.data_queue.close(),this.socket=null})),this.socket.on("error",(t=>{O(`tcp stream to ${this.hostname} ended with error - ${t}`)})),this.socket.on("end",(()=>{this.socket&&(this.socket.destroy(),this.socket=null)})),this.socket.connect({host:t,port:this.port})}))}async recv(){return await this.data_queue.get()}async send(t){await new Promise((e=>{this.socket.write(t,e)}))}async close(){this.socket&&(this.socket.end(),this.socket=null)}pause(){this.data_queue.size>=this.data_queue.max_size&&(this.socket.pause(),this.paused=!0)}resume(){this.socket&&this.paused&&(this.socket.resume(),this.paused=!1)}}class H{constructor(t,e){L(),this.hostname=t,this.port=e,this.connected=!1,this.recv_buffer_size=128,this.data_queue=new M(this.recv_buffer_size)}async connect(){let t=await j(this.hostname),e=a.isIP(t);await new Promise(((s,n)=>{this.socket=null.createSocket(6===e?"udp6":"udp4"),this.socket.on("connect",(()=>{s()})),this.socket.on("message",(t=>{this.data_queue.put(t)})),this.socket.on("error",(()=>{this.connected||n(),this.data_queue.close(),this.socket=null})),this.socket.connect(this.port,t)}))}async recv(){return await this.data_queue.get()}async send(t){this.socket.send(t)}async close(){this.socket&&(this.socket.close(),this.socket=null)}pause(){}resume(){}}var W=s(512);class G extends Error{}function J(t,e){return t===e||t[0]<=e&&t[1]>=e}function K(t,e){let s=!1;for(let n of t)if(e(n)){s=!0;break}return!s}function Q(t,e){for(let s of t)if(e(s))return!0;return!1}function X(t,e){return e.includes(t.range())}async function Y(t,e,s,n){if(!U.allow_tcp_streams&&e===k.TCP)return I.HostBlocked;if(!U.allow_udp_streams&&e===k.UDP)return I.HostBlocked;if(U.hostname_whitelist){if(K(U.hostname_whitelist,(t=>t.test(s))))return I.HostBlocked}else if(U.hostname_blacklist&&Q(U.hostname_blacklist,(t=>t.test(s))))return I.HostBlocked;if(U.port_whitelist){if(K(U.port_whitelist,(t=>J(t,n))))return I.HostBlocked}else if(U.port_blacklist&&Q(U.port_blacklist,(t=>J(t,n))))return I.HostBlocked;let i=s;if(W.isValid(s)){if(!U.allow_direct_ip)return I.HostBlocked}else try{i=await j(s)}catch{}if(function(t){if(!W.isValid(t))return!1;let e=W.parse(t);return!(U.allow_loopback_ips||!X(e,["loopback","unspecified"]))||!(U.allow_private_ips||!X(e,["broadcast","linkLocal","carrierGradeNat","private","reserved"]))}(i))return I.HostBlocked;if(!t)return 0;if(-1!==U.stream_limit_total&&Object.keys(t.streams).length>=U.stream_limit_total)return I.ConnThrottled;if(-1!==U.stream_limit_per_host){let e=0;for(let n of t.streams)n.socket.hostname===s&&e++;if(e>=U.stream_limit_per_host)return I.ConnThrottled}return 0}class Z{static buffer_size=128;constructor(t,e,s){this.stream_id=t,this.conn=e,this.socket=s,this.send_buffer=new M(Z.buffer_size),this.packets_sent=0}async setup(){await this.socket.connect(),this.tcp_to_ws().catch((t=>{N(`(${this.conn.conn_id}) a tcp/udp to ws task encountered an error - ${t}`),this.close()})),this.ws_to_tcp().catch((t=>{N(`(${this.conn.conn_id}) a ws to tcp/udp task encountered an error - ${t}`),this.close()}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause();let e=new w({type:y.type,stream_id:this.stream_id,payload:new y({data:new f(new Uint8Array(t))})});await this.conn.ws.send(e.serialize().bytes),this.socket.resume()}await this.conn.close_stream(this.stream_id,I.Voluntary)}async ws_to_tcp(){for(;;){let t=await this.send_buffer.get();if(null==t)break;if(await this.socket.send(t),this.packets_sent++,this.packets_sent%(Z.buffer_size/2)!=0)continue;let e=new w({type:m.type,stream_id:this.stream_id,payload:new m({buffer_remaining:Z.buffer_size-this.send_buffer.size})});this.conn.ws.send(e.serialize().bytes)}await this.close()}async close(t=null){if(this.send_buffer.close(),this.socket.close(),null==t)return;let e=new w({type:v.type,stream_id:this.stream_id,payload:new v({reason:t})});await this.conn.ws.send(e.serialize().bytes)}async put_data(t){await this.send_buffer.put(t)}}class tt{constructor(t,e,{TCPSocket:s,UDPSocket:n,ping_interval:i}={}){this.ws=new B(t),this.path=e,this.TCPSocket=s||F,this.UDPSocket=n||H,this.ping_interval=i||30,this.ping_task=null,this.streams={},this.conn_id=o.randomUUID().split("-")[0]}async setup(){T(`setting up new wisp connection with id ${this.conn_id}`),await this.ws.connect();let t=new w({type:m.type,stream_id:0,payload:new m({buffer_remaining:Z.buffer_size})});await this.ws.send(t.serialize().bytes),"function"==typeof this.ws.ws.ping&&(this.ping_task=setInterval((()=>{!function(...t){A>0||console.debug(R()+" debug:",...t)}(`(${this.conn_id}) sending websocket ping`),this.ws.ws.ping()}),1e3*this.ping_interval))}create_stream(t,e,s,n){let i=new(e===k.TCP?this.TCPSocket:this.UDPSocket)(s,n),r=new Z(t,this,i);this.streams[t]=r,(async()=>{let i=await Y(this,e,s,n);if(i)return O(`(${this.conn_id}) refusing to create a stream to ${s}:${n}`),void await this.close_stream(t,i,!0);try{await r.setup()}catch(e){O(`(${this.conn_id}) creating a stream to ${s}:${n} failed - ${e}`),await this.close_stream(t,I.NetworkError)}})()}async close_stream(t,e=null,s=!1){let n=this.streams[t];null!=n&&(e&&!s&&T(`(${this.conn_id}) closing stream to ${n.socket.hostname} for reason ${e}`),await n.close(e),delete this.streams[t])}route_packet(t){let e=w.parse_all(t),s=this.streams[e.stream_id];if(null!=s||e.type!=y.type)if(e.type===_.type){let t=e.payload.stream_type===k.TCP?"TCP":"UDP";T(`(${this.conn_id}) opening new ${t} stream to ${e.payload.hostname}:${e.payload.port}`),this.create_stream(e.stream_id,e.payload.stream_type,e.payload.hostname.trim(),e.payload.port)}else e.type===y.type?s.put_data(e.payload.data.bytes):e.type==m.type?O(`(${this.conn_id}) client sent a CONTINUE packet, this should never be possible`):e.type==v.type&&this.close_stream(e.stream_id,e.reason);else O(`(${this.conn_id}) received a DATA packet for a stream which doesn't exist`)}async run(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;try{this.route_packet(new f(new Uint8Array(t)))}catch(t){O(`(${this.conn_id}) routing a packet failed - ${t}`)}}for(let t of Object.keys(this.streams))await this.close_stream(t);clearInterval(this.ping_task),T(`(${this.conn_id}) wisp connection closed`)}}class et{constructor(t,e){let[s,n]=e.split("/").pop().split(":");this.hostname=s.trim(),this.port=parseInt(n),this.ws=new B(t)}async setup(){if(await this.ws.connect(),0!==await Y(null,k.TCP,this.hostname,this.port))throw T(`Refusing to create a wsproxy connection to ${this.hostname}:${this.port}`),this.ws.close(),new G;this.socket=new F(this.hostname,this.port),await this.socket.connect(),this.tcp_to_ws().catch((t=>{N(`a tcp to ws task (wsproxy) encountered an error - ${t}`)})),this.ws_to_tcp().catch((t=>{N(`a ws to tcp task (wsproxy) encountered an error - ${t}`)}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause(),await this.ws.send(t),this.socket.resume()}await this.ws.close()}async ws_to_tcp(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;await this.socket.send(t)}await this.socket.close()}}let st=null;function nt(t,e,s,n={}){L(),t instanceof h.IncomingMessage?st.handleUpgrade(t,e,s,(e=>{it(e,t.url,t,n)})):t instanceof r&&it(ws,"/",{})}async function it(t,e,s,n){T(`new connection on ${e} from ${s.socket.address().address}`);try{if(e.endsWith("/")){let s=new tt(t,e,n);await s.setup(),await s.run()}else{let s=new et(t,e,n);await s.setup()}}catch(e){if(t.close(),e instanceof G)return;N("Uncaught server error:\n"+e.stack)}}q&&(st=new null({noServer:!0}))})(),wisp_full=n})(); | ||
var wisp_full;(()=>{var t={512:function(t){!function(e){"use strict";const s="(0?\\d+|0x[a-f0-9]+)",n={fourOctet:new RegExp(`^${s}\\.${s}\\.${s}\\.${s}$`,"i"),threeOctet:new RegExp(`^${s}\\.${s}\\.${s}$`,"i"),twoOctet:new RegExp(`^${s}\\.${s}$`,"i"),longValue:new RegExp(`^${s}$`,"i")},r=new RegExp("^0[0-7]+$","i"),i=new RegExp("^0x[a-f0-9]+$","i"),o="%[0-9a-z]{1,}",a="(?:[0-9a-f]+::?)+",c={zoneIndex:new RegExp(o,"i"),native:new RegExp(`^(::)?(${a})?([0-9a-f]+)?(::)?(${o})?$`,"i"),deprecatedTransitional:new RegExp(`^(?:::)(${s}\\.${s}\\.${s}\\.${s}(${o})?)$`,"i"),transitional:new RegExp(`^((?:${a})|(?:::)(?:${a})?)${s}\\.${s}\\.${s}\\.${s}(${o})?$`,"i")};function h(t,e){if(t.indexOf("::")!==t.lastIndexOf("::"))return null;let s,n,r=0,i=-1,o=(t.match(c.zoneIndex)||[])[0];for(o&&(o=o.substring(1),t=t.replace(/%.+$/,""));(i=t.indexOf(":",i+1))>=0;)r++;if("::"===t.substr(0,2)&&r--,"::"===t.substr(-2,2)&&r--,r>e)return null;for(n=e-r,s=":";n--;)s+="0:";return":"===(t=t.replace("::",s))[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),{parts:e=function(){const e=t.split(":"),s=[];for(let t=0;t<e.length;t++)s.push(parseInt(e[t],16));return s}(),zoneId:o}}function l(t,e,s,n){if(t.length!==e.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");let r,i=0;for(;n>0;){if(r=s-n,r<0&&(r=0),t[i]>>r!=e[i]>>r)return!1;n-=s,i+=1}return!0}function u(t){if(i.test(t))return parseInt(t,16);if("0"===t[0]&&!isNaN(parseInt(t[1],10))){if(r.test(t))return parseInt(t,8);throw new Error(`ipaddr: cannot parse ${t} as octal`)}return parseInt(t,10)}function p(t,e){for(;t.length<e;)t=`0${t}`;return t}const d={};d.IPv4=function(){function t(t){if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");let e,s;for(e=0;e<t.length;e++)if(s=t[e],!(0<=s&&s<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=t}return t.prototype.SpecialRanges={unspecified:[[new t([0,0,0,0]),8]],broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],carrierGradeNat:[[new t([100,64,0,0]),10]],private:[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,18,0,0]),15],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]],as112:[[new t([192,175,48,0]),24],[new t([192,31,196,0]),24]],amt:[[new t([192,52,193,0]),24]]},t.prototype.kind=function(){return"ipv4"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return l(this.octets,t.octets,8,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0};let n,r,i;for(n=3;n>=0;n-=1){if(r=this.octets[n],!(r in s))return null;if(i=s[r],e&&0!==i)return null;8!==i&&(e=!0),t+=i}return 32-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.toIPv4MappedAddress=function(){return d.IPv6.parse(`::ffff:${this.toString()}`)},t.prototype.toNormalizedString=function(){return this.toString()},t.prototype.toString=function(){return this.octets.join(".")},t}(),d.IPv4.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),n=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),r=[];let i=0;for(;i<4;)r.push(parseInt(s[i],10)|255^parseInt(n[i],10)),i++;return new this(r)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.isIPv4=function(t){return null!==this.parser(t)},d.IPv4.isValid=function(t){try{return new this(this.parser(t)),!0}catch(t){return!1}},d.IPv4.isValidCIDR=function(t){try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv4.isValidFourPartDecimal=function(t){return!(!d.IPv4.isValid(t)||!t.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/))},d.IPv4.networkAddressFromCIDR=function(t){let e,s,n,r,i;try{for(e=this.parseCIDR(t),n=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),r=[],s=0;s<4;)r.push(parseInt(n[s],10)&parseInt(i[s],10)),s++;return new this(r)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.parse=function(t){const e=this.parser(t);if(null===e)throw new Error("ipaddr: string is not formatted like an IPv4 Address");return new this(e)},d.IPv4.parseCIDR=function(t){let e;if(e=t.match(/^(.+)\/(\d+)$/)){const t=parseInt(e[2]);if(t>=0&&t<=32){const s=[this.parse(e[1]),t];return Object.defineProperty(s,"toString",{value:function(){return this.join("/")}}),s}}throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},d.IPv4.parser=function(t){let e,s,r;if(e=t.match(n.fourOctet))return function(){const t=e.slice(1,6),n=[];for(let e=0;e<t.length;e++)s=t[e],n.push(u(s));return n}();if(e=t.match(n.longValue)){if(r=u(e[1]),r>4294967295||r<0)throw new Error("ipaddr: address outside defined range");return function(){const t=[];let e;for(e=0;e<=24;e+=8)t.push(r>>e&255);return t}().reverse()}return(e=t.match(n.twoOctet))?function(){const t=e.slice(1,4),s=[];if(r=u(t[1]),r>16777215||r<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(r>>16&255),s.push(r>>8&255),s.push(255&r),s}():(e=t.match(n.threeOctet))?function(){const t=e.slice(1,5),s=[];if(r=u(t[2]),r>65535||r<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(u(t[1])),s.push(r>>8&255),s.push(255&r),s}():null},d.IPv4.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>32)throw new Error("ipaddr: invalid IPv4 prefix length");const e=[0,0,0,0];let s=0;const n=Math.floor(t/8);for(;s<n;)e[s]=255,s++;return n<4&&(e[n]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.IPv6=function(){function t(t,e){let s,n;if(16===t.length)for(this.parts=[],s=0;s<=14;s+=2)this.parts.push(t[s]<<8|t[s+1]);else{if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=t}for(s=0;s<this.parts.length;s++)if(n=this.parts[s],!(0<=n&&n<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits");e&&(this.zoneId=e)}return t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],discard:[new t([256,0,0,0,0,0,0,0]),64],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],benchmarking:[new t([8193,2,0,0,0,0,0,0]),48],amt:[new t([8193,3,0,0,0,0,0,0]),32],as112v6:[[new t([8193,4,274,0,0,0,0,0]),48],[new t([9760,79,32768,0,0,0,0,0]),48]],deprecated:[new t([8193,16,0,0,0,0,0,0]),28],orchid2:[new t([8193,32,0,0,0,0,0,0]),28],droneRemoteIdProtocolEntityTags:[new t([8193,48,0,0,0,0,0,0]),28],reserved:[[new t([8193,0,0,0,0,0,0,0]),23],[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.kind=function(){return"ipv6"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return l(this.parts,t.parts,16,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:16,32768:15,49152:14,57344:13,61440:12,63488:11,64512:10,65024:9,65280:8,65408:7,65472:6,65504:5,65520:4,65528:3,65532:2,65534:1,65535:0};let n,r;for(let i=7;i>=0;i-=1){if(n=this.parts[i],!(n in s))return null;if(r=s[n],e&&0!==r)return null;16!==r&&(e=!0),t+=r}return 128-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){let t;const e=[],s=this.parts;for(let n=0;n<s.length;n++)t=s[n],e.push(t>>8),e.push(255&t);return e},t.prototype.toFixedLengthString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(p(this.parts[e].toString(16),4));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toIPv4Address=function(){if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");const t=this.parts.slice(-2),e=t[0],s=t[1];return new d.IPv4([e>>8,255&e,s>>8,255&s])},t.prototype.toNormalizedString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(this.parts[e].toString(16));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toRFC5952String=function(){const t=/((^|:)(0(:|$)){2,})/g,e=this.toNormalizedString();let s,n=0,r=-1;for(;s=t.exec(e);)s[0].length>r&&(n=s.index,r=s[0].length);return r<0?e:`${e.substring(0,n)}::${e.substring(n+r)}`},t.prototype.toString=function(){return this.toRFC5952String()},t}(),d.IPv6.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),n=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),r=[];let i=0;for(;i<16;)r.push(parseInt(s[i],10)|255^parseInt(n[i],10)),i++;return new this(r)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.isIPv6=function(t){return null!==this.parser(t)},d.IPv6.isValid=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{const e=this.parser(t);return new this(e.parts,e.zoneId),!0}catch(t){return!1}},d.IPv6.isValidCIDR=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv6.networkAddressFromCIDR=function(t){let e,s,n,r,i;try{for(e=this.parseCIDR(t),n=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),r=[],s=0;s<16;)r.push(parseInt(n[s],10)&parseInt(i[s],10)),s++;return new this(r)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.parse=function(t){const e=this.parser(t);if(null===e.parts)throw new Error("ipaddr: string is not formatted like an IPv6 Address");return new this(e.parts,e.zoneId)},d.IPv6.parseCIDR=function(t){let e,s,n;if((s=t.match(/^(.+)\/(\d+)$/))&&(e=parseInt(s[2]),e>=0&&e<=128))return n=[this.parse(s[1]),e],Object.defineProperty(n,"toString",{value:function(){return this.join("/")}}),n;throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},d.IPv6.parser=function(t){let e,s,n,r,i,o;if(n=t.match(c.deprecatedTransitional))return this.parser(`::ffff:${n[1]}`);if(c.native.test(t))return h(t,8);if((n=t.match(c.transitional))&&(o=n[6]||"",e=n[1],n[1].endsWith("::")||(e=e.slice(0,-1)),e=h(e+o,6),e.parts)){for(i=[parseInt(n[2]),parseInt(n[3]),parseInt(n[4]),parseInt(n[5])],s=0;s<i.length;s++)if(r=i[s],!(0<=r&&r<=255))return null;return e.parts.push(i[0]<<8|i[1]),e.parts.push(i[2]<<8|i[3]),{parts:e.parts,zoneId:e.zoneId}}return null},d.IPv6.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>128)throw new Error("ipaddr: invalid IPv6 prefix length");const e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];let s=0;const n=Math.floor(t/8);for(;s<n;)e[s]=255,s++;return n<16&&(e[n]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.fromByteArray=function(t){const e=t.length;if(4===e)return new d.IPv4(t);if(16===e)return new d.IPv6(t);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},d.isValid=function(t){return d.IPv6.isValid(t)||d.IPv4.isValid(t)},d.isValidCIDR=function(t){return d.IPv6.isValidCIDR(t)||d.IPv4.isValidCIDR(t)},d.parse=function(t){if(d.IPv6.isValid(t))return d.IPv6.parse(t);if(d.IPv4.isValid(t))return d.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},d.parseCIDR=function(t){try{return d.IPv6.parseCIDR(t)}catch(e){try{return d.IPv4.parseCIDR(t)}catch(t){throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},d.process=function(t){const e=this.parse(t);return"ipv6"===e.kind()&&e.isIPv4MappedAddress()?e.toIPv4Address():e},d.subnetMatch=function(t,e,s){let n,r,i,o;for(r in null==s&&(s="unicast"),e)if(Object.prototype.hasOwnProperty.call(e,r))for(i=e[r],!i[0]||i[0]instanceof Array||(i=[i]),n=0;n<i.length;n++)if(o=i[n],t.kind()===o[0].kind()&&t.match.apply(t,o))return r;return s},t.exports?t.exports=d:e.ipaddr=d}(this)}},e={};function s(n){var r=e[n];if(void 0!==r)return r.exports;var i=e[n]={exports:{}};return t[n].call(i.exports,i,i.exports,s),i.exports}s.d=(t,e)=>{for(var n in e)s.o(e,n)&&!s.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};(()=>{"use strict";s.r(n),s.d(n,{client:()=>e,packet:()=>t,server:()=>r});var t={};s.r(t),s.d(t,{ClosePayload:()=>v,ConnectPayload:()=>_,ContinuePayload:()=>m,DataPayload:()=>y,WispBuffer:()=>f,WispPacket:()=>w,close_reasons:()=>I,packet_classes:()=>g,packet_types:()=>b,stream_types:()=>k});var e={};s.r(e),s.d(e,{ClientConnection:()=>$,WispWebSocket:()=>z,_wisp_connections:()=>C});var r={};s.r(r),s.d(r,{ServerConnection:()=>at,ServerStream:()=>ot,options:()=>M,routeRequest:()=>lt});const i=globalThis.WebSocket,o=globalThis.crypto,a=null,c=null,h=null,l=new TextEncoder,u=l.encode.bind(l),p=new TextDecoder,d=p.decode.bind(p);class f{constructor(t){if(t instanceof Uint8Array)this.from_array(t);else if("number"==typeof t)this.from_array(new Uint8Array(t));else{if("string"!=typeof t)throw console.trace(),"invalid data type passed to wisp buffer constructor";this.from_array(u(t))}}from_array(t){this.size=t.length,this.bytes=t,this.view=new DataView(t.buffer)}concat(t){let e=new f(this.size+t.size);return e.bytes.set(this.bytes,0),e.bytes.set(t.bytes,this.size),e}slice(t,e){let s=this.bytes.slice(t,e);return new f(s)}}class w{static min_size=5;constructor({type:t,stream_id:e,payload:s,payload_bytes:n}){this.type=t,this.stream_id=e,this.payload_bytes=n,this.payload=s}static parse(t){return new w({type:t.view.getUint8(0),stream_id:t.view.getUint32(1,!0),payload_bytes:t.slice(5)})}static parse_all(t){if(t.size<w.min_size)throw"packet too small";let e=w.parse(t),s=g[e.type];if(void 0===s)throw"invalid packet type";if(e.payload_bytes.size<s.size)throw"payload too small";return e.payload=s.parse(e.payload_bytes),e}serialize(){let t=new f(5);return t.view.setUint8(0,this.type),t.view.setUint32(1,this.stream_id,!0),t=t.concat(this.payload.serialize()),t}}class _{static min_size=3;static type=1;static name="CONNECT";constructor({stream_type:t,port:e,hostname:s}){this.stream_type=t,this.port=e,this.hostname=s}static parse(t){return new _({stream_type:t.view.getUint8(0),port:t.view.getUint16(1,!0),hostname:d(t.slice(3).bytes)})}serialize(){let t=new f(3);return t.view.setUint8(0,this.stream_type),t.view.setUint16(1,this.port,!0),t=t.concat(new f(this.hostname)),t}}class y{static min_size=0;static type=2;static name="DATA";constructor({data:t}){this.data=t}static parse(t){return new y({data:t})}serialize(){return this.data}}class m{static type=3;static name="CONTINUE";constructor({buffer_remaining:t}){this.buffer_remaining=t}static parse(t){return new m({buffer_remaining:t.view.getUint32(0,!0)})}serialize(){let t=new f(4);return t.view.setUint32(0,this.buffer_remaining,!0),t}}class v{static min_size=1;static type=4;static name="CLOSE";constructor({reason:t}){this.reason=t}static parse(t){return new v({reason:t.view.getUint8(0)})}serialize(){let t=new f(1);return t.view.setUint8(0,this.buffer_remaining),t}}const g=[void 0,_,y,m,v],b={CONNECT:1,DATA:2,CONTINUE:3,CLOSE:4},k={TCP:1,UDP:2},I={Unknown:1,Voluntary:2,NetworkError:3,InvalidInfo:65,UnreachableHost:66,NoResponse:67,ConnRefused:68,TransferTimeout:71,HostBlocked:72,ConnThrottled:73,ClientError:129};class P{constructor(t,e,s,n,r,i,o){this.hostname=t,this.port=e,this.ws=s,this.buffer_size=n,this.stream_id=r,this.connection=i,this.stream_type=o,this.send_buffer=[],this.open=!0,this.onopen=()=>{},this.onclose=()=>{},this.onmessage=()=>{}}send(t){if(this.buffer_size>0||!this.open||this.stream_type===k.UDP){let e=new w({type:b.DATA,stream_id:this.stream_id,payload:new y({data:new f(t)})});this.ws.send(e.serialize().bytes),this.buffer_size--}else this.send_buffer.push(t)}continue_received(t){for(this.buffer_size=t;this.buffer_size>0&&this.send_buffer.length>0;)this.send(this.send_buffer.shift())}close(t=1){if(!this.open)return;let e=new w({type:b.CLOSE,stream_id,payload:new v({reason:t})});this.ws.send(e.serialize().bytes),this.open=!1,delete this.connection.active_streams[this.stream_id]}}class ${constructor(t){if(!t.endsWith("/"))throw"wisp endpoints must end with a trailing forward slash";this.wisp_url=t,this.max_buffer_size=null,this.active_streams={},this.connected=!1,this.connecting=!1,this.next_stream_id=1,this.onopen=()=>{},this.onclose=()=>{},this.onerror=()=>{},this.onmessage=()=>{},this.connect_ws()}connect_ws(){this.ws=new i(this.wisp_url),this.ws.binaryType="arraybuffer",this.connecting=!0,this.ws.onerror=()=>{this.on_ws_close(),this.onerror()},this.ws.onclose=()=>{this.on_ws_close(),this.onclose()},this.ws.onmessage=t=>{this.on_ws_msg(t),this.connecting&&(this.connected=!0,this.connecting=!1,this.onopen())}}close_stream(t,e){t.onclose(e),delete this.active_streams[t.stream_id]}on_ws_close(){this.connected=!1,this.connecting=!1;for(let t of Object.keys(this.active_streams))this.close_stream(this.active_streams[t],3)}create_stream(t,e,s="tcp"){let n="udp"===s?2:1,r=this.next_stream_id++,i=new P(t,e,this.ws,this.max_buffer_size,r,this,n);this.active_streams[r]=i,i.open=this.connected;let o=new w({type:b.CONNECT,stream_id:r,payload:new _({stream_type:n,port:e,hostname:t})});return this.ws.send(o.serialize().bytes),i}on_ws_msg(t){let e=new f(new Uint8Array(t.data));if(e.size<w.min_size)return void console.warn("wisp client warning: received a packet which is too short");let s=w.parse_all(e),n=this.active_streams[s.stream_id];void 0!==n||0===s.stream_id&&s.type===b.CONTINUE?s.type===b.DATA?n.onmessage(s.payload_bytes.bytes):s.type===b.CONTINUE&&0==s.stream_id?this.max_buffer_size=s.payload.buffer_remaining:s.type===b.CONTINUE?n.continue_received(s.payload.buffer_size):s.type===b.CLOSE?this.close_stream(n,s.payload.reason):console.warn(`wisp client warning: receive an invalid packet of type ${s.type}`):console.warn(`wisp client warning: received a ${g[s.type].name} packet for a stream which doesn't exist`)}}const E=globalThis.CloseEvent||Event,C={};class z extends EventTarget{constructor(t,e){super(),this.url=t,this.protocols=e,this.binaryType="blob",this.stream=null,this.connection=null,this.onopen=()=>{},this.onerror=()=>{},this.onmessage=()=>{},this.onclose=()=>{},this.CONNECTING=0,this.OPEN=1,this.CLOSING=2,this.CLOSED=3,this._ready_state=this.CONNECTING;let s=this.url.split("/"),n=s.pop().split(":");this.host=n[0],this.port=parseInt(n[1]),this.real_url=s.join("/")+"/",this.init_connection()}on_conn_close(){this._ready_state=this.CLOSED,C[this.real_url]&&(this.onerror(new Event("error")),this.dispatchEvent(new Event("error"))),delete C[this.real_url]}init_connection(){if(this.connection=C[this.real_url],this.connection)if(this.connection.connected)this.connection=C[this.real_url],this.init_stream();else{let t=this.connection.onopen;this.connection.onopen=()=>{t(),this.init_stream()}}else this.connection=new $(this.real_url),this.connection.onopen=()=>{this.init_stream()},this.connection.onclose=()=>{this.on_conn_close()},this.connection.onerror=()=>{this.on_conn_close()},C[this.real_url]=this.connection}init_stream(){this._ready_state=this.OPEN,this.stream=this.connection.create_stream(this.host,this.port),this.stream.onmessage=t=>{let e;if("blob"==this.binaryType)e=new Blob(t);else{if("arraybuffer"!=this.binaryType)throw"invalid binaryType string";e=t.buffer}let s=new MessageEvent("message",{data:e});this.onmessage(s),this.dispatchEvent(s)},this.stream.onclose=t=>{this._ready_state=this.CLOSED;let e=new E("close",{code:t});this.onclose(e),this.dispatchEvent(e)};let t=new Event("open");this.onopen(t),this.dispatchEvent(t)}send(t){let e;if(t instanceof Uint8Array)e=t;else if("string"==typeof t)e=(new TextEncoder).encode(t);else{if(t instanceof Blob)return void t.arrayBuffer().then((t=>{this.send(t)}));if(t instanceof ArrayBuffer)e=new Uint8Array(t);else{if(!ArrayBuffer.isView(t))throw"invalid data type to be sent";e=new Uint8Array(t.buffer)}}if(!this.stream)throw"websocket is not ready";this.stream.send(e)}close(){this.stream.close(2)}get bufferedAmount(){let t=0;for(let e of this.stream.send_buffer)t+=e.length;return t}get extensions(){return""}get protocol(){return"binary"}get readyState(){return this._ready_state}}const x=0,D=1,S=2,R=3;let A=D;function T(){let[t,e]=(new Date).toJSON().split("T");return t=t.replaceAll("-","/"),e=e.split(".")[0],`[${t} - ${e}]`}function O(...t){A>x||console.debug(T()+" debug:",...t)}function N(...t){A>D||console.info(T()+" info:",...t)}function U(...t){A>S||console.warn(T()+" warn:",...t)}function B(...t){A>R||console.error(T()+" error:",...t)}const M={hostname_blacklist:null,hostname_whitelist:null,port_blacklist:null,port_whitelist:null,allow_direct_ip:!0,allow_private_ips:!1,allow_loopback_ips:!1,client_ip_blacklist:null,client_ip_whitelist:null,stream_limit_per_host:-1,stream_limit_total:-1,allow_udp_streams:!0,allow_tcp_streams:!0,dns_ttl:120,dns_method:"lookup",dns_servers:null,dns_result_order:"verbatim"};class q{send_buffer_size=33554432;constructor(t){this.ws=t,this.connected=!1,this.data_queue=new V(1)}async connect(){await new Promise(((t,e)=>{this.ws.onopen=()=>{this.connected=!0,t()},this.ws.onmessage=t=>{this.data_queue.put(t.data)},this.ws.onclose=()=>{this.connected?this.data_queue.close():e()},this.ws.readyState===this.ws.OPEN&&(this.connected=!0,t())}))}async recv(){return await this.data_queue.get()}async send(t){if(this.ws.send(t),!(this.ws.bufferedAmount<=this.send_buffer_size))for(;!(this.ws.bufferedAmount<=this.send_buffer_size/2);)await new Promise((t=>{setTimeout(t,10)}))}close(t,e){this.ws.close(t,e),this.data_queue.close()}get buffered_amount(){return this.ws.bufferedAmount}}class V{constructor(t){this.max_size=t,this.queue=[],this.put_callbacks=[],this.get_callbacks=[]}put_now(t){this.queue.push(t),this.get_callbacks.shift()?.()}async put(t){this.size<=this.max_size||await new Promise((t=>{this.put_callbacks.push(t)})),this.put_now(t)}get_now(){return this.put_callbacks.shift()?.(),this.queue.shift()}async get(){return this.size>0||await new Promise((t=>{this.get_callbacks.push(t)})),this.get_now()}close(){let t;for(this.queue=[];t=this.get_callbacks.shift();)t();for(;t=this.put_callbacks.shift();)t()}get size(){return this.queue.length}}const L="undefined"!=typeof process,j=new Map;let F=null,H=null;function W(){if(!L)throw"not running on node.js"}function G(t){return H.resolve4(t)}function J(t){return H.resolve6(t)}async function K(t,e,s){try{return(await t(s))[0]}catch{return(await e(s))[0]}}async function Q(t){if(!L)return t;let e=a.isIP(t);if(4===e||6===e)return t;let s=Date.now();for(let[t,e]of j)s-e.time>M.dns_ttl&&j.delete(t);let n,r=j.get(t);if(r){if(r.error)throw r.error;return r.address}try{n=await async function(t){if("lookup"===M.dns_method)return(await c.lookup(t,{order:M.dns_result_order})).address;if("resolve"===M.dns_method){if(H||(H=new c.Resolver),M.dns_servers!==F&&(O("Setting custom DNS servers to: "+M.dns_servers.join(", ")),H.setServers(M.dns_servers),F=M.dns_servers),"verbatim"===M.dns_result_order||"ipv6first"===M.dns_result_order)return await K(J,G,t);if("ipv4first"===M.dns_result_order)return await K(G,J,t);throw new Error("Invalid result order. options.dns_result_order must be either 'ipv6first', 'ipv4first', or 'verbatim'.")}if("function"==typeof M.dns_method)return await M.dns_method(t);throw new Error("Invalid DNS method. options.dns_method must either be 'lookup' or 'resolve'.")}(t),O(`Domain resolved: ${t} -> ${n}`),j.set(t,{time:Date.now(),address:n})}catch(e){throw j.set(t,{time:Date.now(),error:e}),e}return n}class X{constructor(t,e){W(),this.hostname=t,this.port=e,this.recv_buffer_size=128,this.socket=null,this.paused=!1,this.connected=!1,this.data_queue=new V(this.recv_buffer_size)}async connect(){let t=await Q(this.hostname);await new Promise(((e,s)=>{this.socket=new a.Socket,this.socket.setNoDelay(!0),this.socket.on("connect",(()=>{this.connected=!0,e()})),this.socket.on("data",(t=>{this.data_queue.put(t)})),this.socket.on("close",(t=>{t&&!this.connected?s():this.data_queue.close(),this.socket=null})),this.socket.on("error",(t=>{U(`tcp stream to ${this.hostname} ended with error - ${t}`)})),this.socket.on("end",(()=>{this.socket&&(this.socket.destroy(),this.socket=null)})),this.socket.connect({host:t,port:this.port})}))}async recv(){return await this.data_queue.get()}async send(t){await new Promise((e=>{this.socket.write(t,e)}))}async close(){this.socket&&(this.socket.end(),this.socket=null)}pause(){this.data_queue.size>=this.data_queue.max_size&&(this.socket.pause(),this.paused=!0)}resume(){this.socket&&this.paused&&(this.socket.resume(),this.paused=!1)}}class Y{constructor(t,e){W(),this.hostname=t,this.port=e,this.connected=!1,this.recv_buffer_size=128,this.data_queue=new V(this.recv_buffer_size)}async connect(){let t=await Q(this.hostname),e=a.isIP(t);await new Promise(((s,n)=>{this.socket=null.createSocket(6===e?"udp6":"udp4"),this.socket.on("connect",(()=>{s()})),this.socket.on("message",(t=>{this.data_queue.put(t)})),this.socket.on("error",(()=>{this.connected||n(),this.data_queue.close(),this.socket=null})),this.socket.connect(this.port,t)}))}async recv(){return await this.data_queue.get()}async send(t){this.socket.send(t)}async close(){this.socket&&(this.socket.close(),this.socket=null)}pause(){}resume(){}}var Z=s(512);class tt extends Error{}function et(t,e){return t===e||t[0]<=e&&t[1]>=e}function st(t,e){let s=!1;for(let n of t)if(e(n)){s=!0;break}return!s}function nt(t,e){for(let s of t)if(e(s))return!0;return!1}function rt(t,e){return e.includes(t.range())}async function it(t,e,s,n){if(!M.allow_tcp_streams&&e===k.TCP)return I.HostBlocked;if(!M.allow_udp_streams&&e===k.UDP)return I.HostBlocked;if(M.hostname_whitelist){if(st(M.hostname_whitelist,(t=>t.test(s))))return I.HostBlocked}else if(M.hostname_blacklist&&nt(M.hostname_blacklist,(t=>t.test(s))))return I.HostBlocked;if(M.port_whitelist){if(st(M.port_whitelist,(t=>et(t,n))))return I.HostBlocked}else if(M.port_blacklist&&nt(M.port_blacklist,(t=>et(t,n))))return I.HostBlocked;let r=s;if(Z.isValid(s)){if(!M.allow_direct_ip)return I.HostBlocked}else try{r=await Q(s)}catch{}if(function(t){if(!Z.isValid(t))return!1;let e=Z.parse(t);return!(M.allow_loopback_ips||!rt(e,["loopback","unspecified"]))||!(M.allow_private_ips||!rt(e,["broadcast","linkLocal","carrierGradeNat","private","reserved"]))}(r))return I.HostBlocked;if(!t)return 0;if(-1!==M.stream_limit_total&&Object.keys(t.streams).length>=M.stream_limit_total)return I.ConnThrottled;if(-1!==M.stream_limit_per_host){let e=0;for(let n of t.streams)n.socket.hostname===s&&e++;if(e>=M.stream_limit_per_host)return I.ConnThrottled}return 0}class ot{static buffer_size=128;constructor(t,e,s){this.stream_id=t,this.conn=e,this.socket=s,this.send_buffer=new V(ot.buffer_size),this.packets_sent=0}async setup(){await this.socket.connect(),this.tcp_to_ws().catch((t=>{B(`(${this.conn.conn_id}) a tcp/udp to ws task encountered an error - ${t}`),this.close()})),this.ws_to_tcp().catch((t=>{B(`(${this.conn.conn_id}) a ws to tcp/udp task encountered an error - ${t}`),this.close()}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause();let e=new w({type:y.type,stream_id:this.stream_id,payload:new y({data:new f(new Uint8Array(t))})});await this.conn.ws.send(e.serialize().bytes),this.socket.resume()}await this.conn.close_stream(this.stream_id,I.Voluntary)}async ws_to_tcp(){for(;;){let t=await this.send_buffer.get();if(null==t)break;if(await this.socket.send(t),this.packets_sent++,this.packets_sent%(ot.buffer_size/2)!=0)continue;let e=new w({type:m.type,stream_id:this.stream_id,payload:new m({buffer_remaining:ot.buffer_size-this.send_buffer.size})});this.conn.ws.send(e.serialize().bytes)}await this.close()}async close(t=null){if(this.send_buffer.close(),this.socket.close(),null==t)return;let e=new w({type:v.type,stream_id:this.stream_id,payload:new v({reason:t})});await this.conn.ws.send(e.serialize().bytes)}async put_data(t){await this.send_buffer.put(t)}}class at{constructor(t,e,{TCPSocket:s,UDPSocket:n,ping_interval:r}={}){this.ws=new q(t),this.path=e,this.TCPSocket=s||X,this.UDPSocket=n||Y,this.ping_interval=r||30,this.ping_task=null,this.streams={},this.conn_id=o.randomUUID().split("-")[0]}async setup(){N(`setting up new wisp connection with id ${this.conn_id}`),await this.ws.connect();let t=new w({type:m.type,stream_id:0,payload:new m({buffer_remaining:ot.buffer_size})});await this.ws.send(t.serialize().bytes),"function"==typeof this.ws.ws.ping&&(this.ping_task=setInterval((()=>{O(`(${this.conn_id}) sending websocket ping`),this.ws.ws.ping()}),1e3*this.ping_interval))}create_stream(t,e,s,n){let r=new(e===k.TCP?this.TCPSocket:this.UDPSocket)(s,n),i=new ot(t,this,r);this.streams[t]=i,(async()=>{let r=await it(this,e,s,n);if(r)return U(`(${this.conn_id}) refusing to create a stream to ${s}:${n}`),void await this.close_stream(t,r,!0);try{await i.setup()}catch(e){U(`(${this.conn_id}) creating a stream to ${s}:${n} failed - ${e}`),await this.close_stream(t,I.NetworkError)}})()}async close_stream(t,e=null,s=!1){let n=this.streams[t];null!=n&&(e&&!s&&N(`(${this.conn_id}) closing stream to ${n.socket.hostname} for reason ${e}`),await n.close(e),delete this.streams[t])}route_packet(t){let e=w.parse_all(t),s=this.streams[e.stream_id];if(null!=s||e.type!=y.type)if(e.type===_.type){let t=e.payload.stream_type===k.TCP?"TCP":"UDP";N(`(${this.conn_id}) opening new ${t} stream to ${e.payload.hostname}:${e.payload.port}`),this.create_stream(e.stream_id,e.payload.stream_type,e.payload.hostname.trim(),e.payload.port)}else e.type===y.type?s.put_data(e.payload.data.bytes):e.type==m.type?U(`(${this.conn_id}) client sent a CONTINUE packet, this should never be possible`):e.type==v.type&&this.close_stream(e.stream_id,e.reason);else U(`(${this.conn_id}) received a DATA packet for a stream which doesn't exist`)}async run(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;try{this.route_packet(new f(new Uint8Array(t)))}catch(t){U(`(${this.conn_id}) routing a packet failed - ${t}`)}}for(let t of Object.keys(this.streams))await this.close_stream(t);clearInterval(this.ping_task),N(`(${this.conn_id}) wisp connection closed`)}}class ct{constructor(t,e){let[s,n]=e.split("/").pop().split(":");this.hostname=s.trim(),this.port=parseInt(n),this.ws=new q(t)}async setup(){if(await this.ws.connect(),0!==await it(null,k.TCP,this.hostname,this.port))throw N(`Refusing to create a wsproxy connection to ${this.hostname}:${this.port}`),this.ws.close(),new tt;this.socket=new X(this.hostname,this.port),await this.socket.connect(),this.tcp_to_ws().catch((t=>{B(`a tcp to ws task (wsproxy) encountered an error - ${t}`)})),this.ws_to_tcp().catch((t=>{B(`a ws to tcp task (wsproxy) encountered an error - ${t}`)}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause(),await this.ws.send(t),this.socket.resume()}await this.ws.close()}async ws_to_tcp(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;await this.socket.send(t)}await this.socket.close()}}let ht=null;function lt(t,e,s,n={}){W(),t instanceof h.IncomingMessage?ht.handleUpgrade(t,e,s,(e=>{ut(e,t.url,t,n)})):t instanceof i&&ut(ws,"/",{})}async function ut(t,e,s,n){N(`new connection on ${e} from ${s.socket.address().address}`);try{if(e.endsWith("/")){let s=new at(t,e,n);await s.setup(),await s.run()}else{let s=new ct(t,e,n);await s.setup()}}catch(e){if(t.close(),e instanceof tt)return;B("Uncaught server error:\n"+e.stack)}}L&&(ht=new null({noServer:!0}))})(),wisp_full=n})(); |
@@ -1,1 +0,1 @@ | ||
var wisp_server;(()=>{var t={512:function(t){!function(e){"use strict";const s="(0?\\d+|0x[a-f0-9]+)",r={fourOctet:new RegExp(`^${s}\\.${s}\\.${s}\\.${s}$`,"i"),threeOctet:new RegExp(`^${s}\\.${s}\\.${s}$`,"i"),twoOctet:new RegExp(`^${s}\\.${s}$`,"i"),longValue:new RegExp(`^${s}$`,"i")},n=new RegExp("^0[0-7]+$","i"),i=new RegExp("^0x[a-f0-9]+$","i"),o="%[0-9a-z]{1,}",a="(?:[0-9a-f]+::?)+",c={zoneIndex:new RegExp(o,"i"),native:new RegExp(`^(::)?(${a})?([0-9a-f]+)?(::)?(${o})?$`,"i"),deprecatedTransitional:new RegExp(`^(?:::)(${s}\\.${s}\\.${s}\\.${s}(${o})?)$`,"i"),transitional:new RegExp(`^((?:${a})|(?:::)(?:${a})?)${s}\\.${s}\\.${s}\\.${s}(${o})?$`,"i")};function l(t,e){if(t.indexOf("::")!==t.lastIndexOf("::"))return null;let s,r,n=0,i=-1,o=(t.match(c.zoneIndex)||[])[0];for(o&&(o=o.substring(1),t=t.replace(/%.+$/,""));(i=t.indexOf(":",i+1))>=0;)n++;if("::"===t.substr(0,2)&&n--,"::"===t.substr(-2,2)&&n--,n>e)return null;for(r=e-n,s=":";r--;)s+="0:";return":"===(t=t.replace("::",s))[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),{parts:e=function(){const e=t.split(":"),s=[];for(let t=0;t<e.length;t++)s.push(parseInt(e[t],16));return s}(),zoneId:o}}function h(t,e,s,r){if(t.length!==e.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");let n,i=0;for(;r>0;){if(n=s-r,n<0&&(n=0),t[i]>>n!=e[i]>>n)return!1;r-=s,i+=1}return!0}function u(t){if(i.test(t))return parseInt(t,16);if("0"===t[0]&&!isNaN(parseInt(t[1],10))){if(n.test(t))return parseInt(t,8);throw new Error(`ipaddr: cannot parse ${t} as octal`)}return parseInt(t,10)}function p(t,e){for(;t.length<e;)t=`0${t}`;return t}const d={};d.IPv4=function(){function t(t){if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");let e,s;for(e=0;e<t.length;e++)if(s=t[e],!(0<=s&&s<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=t}return t.prototype.SpecialRanges={unspecified:[[new t([0,0,0,0]),8]],broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],carrierGradeNat:[[new t([100,64,0,0]),10]],private:[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,18,0,0]),15],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]],as112:[[new t([192,175,48,0]),24],[new t([192,31,196,0]),24]],amt:[[new t([192,52,193,0]),24]]},t.prototype.kind=function(){return"ipv4"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return h(this.octets,t.octets,8,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0};let r,n,i;for(r=3;r>=0;r-=1){if(n=this.octets[r],!(n in s))return null;if(i=s[n],e&&0!==i)return null;8!==i&&(e=!0),t+=i}return 32-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.toIPv4MappedAddress=function(){return d.IPv6.parse(`::ffff:${this.toString()}`)},t.prototype.toNormalizedString=function(){return this.toString()},t.prototype.toString=function(){return this.octets.join(".")},t}(),d.IPv4.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[];let i=0;for(;i<4;)n.push(parseInt(s[i],10)|255^parseInt(r[i],10)),i++;return new this(n)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.isIPv4=function(t){return null!==this.parser(t)},d.IPv4.isValid=function(t){try{return new this(this.parser(t)),!0}catch(t){return!1}},d.IPv4.isValidCIDR=function(t){try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv4.isValidFourPartDecimal=function(t){return!(!d.IPv4.isValid(t)||!t.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/))},d.IPv4.networkAddressFromCIDR=function(t){let e,s,r,n,i;try{for(e=this.parseCIDR(t),r=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[],s=0;s<4;)n.push(parseInt(r[s],10)&parseInt(i[s],10)),s++;return new this(n)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.parse=function(t){const e=this.parser(t);if(null===e)throw new Error("ipaddr: string is not formatted like an IPv4 Address");return new this(e)},d.IPv4.parseCIDR=function(t){let e;if(e=t.match(/^(.+)\/(\d+)$/)){const t=parseInt(e[2]);if(t>=0&&t<=32){const s=[this.parse(e[1]),t];return Object.defineProperty(s,"toString",{value:function(){return this.join("/")}}),s}}throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},d.IPv4.parser=function(t){let e,s,n;if(e=t.match(r.fourOctet))return function(){const t=e.slice(1,6),r=[];for(let e=0;e<t.length;e++)s=t[e],r.push(u(s));return r}();if(e=t.match(r.longValue)){if(n=u(e[1]),n>4294967295||n<0)throw new Error("ipaddr: address outside defined range");return function(){const t=[];let e;for(e=0;e<=24;e+=8)t.push(n>>e&255);return t}().reverse()}return(e=t.match(r.twoOctet))?function(){const t=e.slice(1,4),s=[];if(n=u(t[1]),n>16777215||n<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(n>>16&255),s.push(n>>8&255),s.push(255&n),s}():(e=t.match(r.threeOctet))?function(){const t=e.slice(1,5),s=[];if(n=u(t[2]),n>65535||n<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(u(t[1])),s.push(n>>8&255),s.push(255&n),s}():null},d.IPv4.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>32)throw new Error("ipaddr: invalid IPv4 prefix length");const e=[0,0,0,0];let s=0;const r=Math.floor(t/8);for(;s<r;)e[s]=255,s++;return r<4&&(e[r]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.IPv6=function(){function t(t,e){let s,r;if(16===t.length)for(this.parts=[],s=0;s<=14;s+=2)this.parts.push(t[s]<<8|t[s+1]);else{if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=t}for(s=0;s<this.parts.length;s++)if(r=this.parts[s],!(0<=r&&r<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits");e&&(this.zoneId=e)}return t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],discard:[new t([256,0,0,0,0,0,0,0]),64],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],benchmarking:[new t([8193,2,0,0,0,0,0,0]),48],amt:[new t([8193,3,0,0,0,0,0,0]),32],as112v6:[[new t([8193,4,274,0,0,0,0,0]),48],[new t([9760,79,32768,0,0,0,0,0]),48]],deprecated:[new t([8193,16,0,0,0,0,0,0]),28],orchid2:[new t([8193,32,0,0,0,0,0,0]),28],droneRemoteIdProtocolEntityTags:[new t([8193,48,0,0,0,0,0,0]),28],reserved:[[new t([8193,0,0,0,0,0,0,0]),23],[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.kind=function(){return"ipv6"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return h(this.parts,t.parts,16,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:16,32768:15,49152:14,57344:13,61440:12,63488:11,64512:10,65024:9,65280:8,65408:7,65472:6,65504:5,65520:4,65528:3,65532:2,65534:1,65535:0};let r,n;for(let i=7;i>=0;i-=1){if(r=this.parts[i],!(r in s))return null;if(n=s[r],e&&0!==n)return null;16!==n&&(e=!0),t+=n}return 128-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){let t;const e=[],s=this.parts;for(let r=0;r<s.length;r++)t=s[r],e.push(t>>8),e.push(255&t);return e},t.prototype.toFixedLengthString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(p(this.parts[e].toString(16),4));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toIPv4Address=function(){if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");const t=this.parts.slice(-2),e=t[0],s=t[1];return new d.IPv4([e>>8,255&e,s>>8,255&s])},t.prototype.toNormalizedString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(this.parts[e].toString(16));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toRFC5952String=function(){const t=/((^|:)(0(:|$)){2,})/g,e=this.toNormalizedString();let s,r=0,n=-1;for(;s=t.exec(e);)s[0].length>n&&(r=s.index,n=s[0].length);return n<0?e:`${e.substring(0,r)}::${e.substring(r+n)}`},t.prototype.toString=function(){return this.toRFC5952String()},t}(),d.IPv6.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[];let i=0;for(;i<16;)n.push(parseInt(s[i],10)|255^parseInt(r[i],10)),i++;return new this(n)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.isIPv6=function(t){return null!==this.parser(t)},d.IPv6.isValid=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{const e=this.parser(t);return new this(e.parts,e.zoneId),!0}catch(t){return!1}},d.IPv6.isValidCIDR=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv6.networkAddressFromCIDR=function(t){let e,s,r,n,i;try{for(e=this.parseCIDR(t),r=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[],s=0;s<16;)n.push(parseInt(r[s],10)&parseInt(i[s],10)),s++;return new this(n)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.parse=function(t){const e=this.parser(t);if(null===e.parts)throw new Error("ipaddr: string is not formatted like an IPv6 Address");return new this(e.parts,e.zoneId)},d.IPv6.parseCIDR=function(t){let e,s,r;if((s=t.match(/^(.+)\/(\d+)$/))&&(e=parseInt(s[2]),e>=0&&e<=128))return r=[this.parse(s[1]),e],Object.defineProperty(r,"toString",{value:function(){return this.join("/")}}),r;throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},d.IPv6.parser=function(t){let e,s,r,n,i,o;if(r=t.match(c.deprecatedTransitional))return this.parser(`::ffff:${r[1]}`);if(c.native.test(t))return l(t,8);if((r=t.match(c.transitional))&&(o=r[6]||"",e=r[1],r[1].endsWith("::")||(e=e.slice(0,-1)),e=l(e+o,6),e.parts)){for(i=[parseInt(r[2]),parseInt(r[3]),parseInt(r[4]),parseInt(r[5])],s=0;s<i.length;s++)if(n=i[s],!(0<=n&&n<=255))return null;return e.parts.push(i[0]<<8|i[1]),e.parts.push(i[2]<<8|i[3]),{parts:e.parts,zoneId:e.zoneId}}return null},d.IPv6.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>128)throw new Error("ipaddr: invalid IPv6 prefix length");const e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];let s=0;const r=Math.floor(t/8);for(;s<r;)e[s]=255,s++;return r<16&&(e[r]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.fromByteArray=function(t){const e=t.length;if(4===e)return new d.IPv4(t);if(16===e)return new d.IPv6(t);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},d.isValid=function(t){return d.IPv6.isValid(t)||d.IPv4.isValid(t)},d.isValidCIDR=function(t){return d.IPv6.isValidCIDR(t)||d.IPv4.isValidCIDR(t)},d.parse=function(t){if(d.IPv6.isValid(t))return d.IPv6.parse(t);if(d.IPv4.isValid(t))return d.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},d.parseCIDR=function(t){try{return d.IPv6.parseCIDR(t)}catch(e){try{return d.IPv4.parseCIDR(t)}catch(t){throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},d.process=function(t){const e=this.parse(t);return"ipv6"===e.kind()&&e.isIPv4MappedAddress()?e.toIPv4Address():e},d.subnetMatch=function(t,e,s){let r,n,i,o;for(n in null==s&&(s="unicast"),e)if(Object.prototype.hasOwnProperty.call(e,n))for(i=e[n],!i[0]||i[0]instanceof Array||(i=[i]),r=0;r<i.length;r++)if(o=i[r],t.kind()===o[0].kind()&&t.match.apply(t,o))return n;return s},t.exports?t.exports=d:e.ipaddr=d}(this)}},e={};function s(r){var n=e[r];if(void 0!==n)return n.exports;var i=e[r]={exports:{}};return t[r].call(i.exports,i,i.exports,s),i.exports}s.d=(t,e)=>{for(var r in e)s.o(e,r)&&!s.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};(()=>{"use strict";s.r(r),s.d(r,{logging:()=>t,packet:()=>e,server:()=>n});var t={};s.r(t),s.d(t,{DEBUG:()=>i,ERROR:()=>c,INFO:()=>o,NONE:()=>l,WARN:()=>a,debug:()=>d,error:()=>y,get_timestamp:()=>u,info:()=>f,log:()=>w,log_level:()=>h,set_level:()=>p,warn:()=>_});var e={};s.r(e),s.d(e,{ClosePayload:()=>C,ConnectPayload:()=>P,ContinuePayload:()=>z,DataPayload:()=>$,WispBuffer:()=>I,WispPacket:()=>b,close_reasons:()=>D,packet_classes:()=>R,packet_types:()=>E,stream_types:()=>x});var n={};s.r(n),s.d(n,{ServerConnection:()=>tt,ServerStream:()=>Z,options:()=>S,routeRequest:()=>rt});const i=0,o=1,a=2,c=3,l=4;let h=o;function u(){let[t,e]=(new Date).toJSON().split("T");return t=t.replaceAll("-","/"),e=e.split(".")[0],`[${t} - ${e}]`}function p(t){h=t}function d(...t){h>i||console.debug(u()+" debug:",...t)}function f(...t){h>o||console.info(u()+" info:",...t)}function w(...t){h>o||console.log(u()+" log:",...t)}function _(...t){h>a||console.warn(u()+" warn:",...t)}function y(...t){h>c||console.error(u()+" error:",...t)}const m=new TextEncoder,v=m.encode.bind(m),g=new TextDecoder,k=g.decode.bind(g);class I{constructor(t){if(t instanceof Uint8Array)this.from_array(t);else if("number"==typeof t)this.from_array(new Uint8Array(t));else{if("string"!=typeof t)throw console.trace(),"invalid data type passed to wisp buffer constructor";this.from_array(v(t))}}from_array(t){this.size=t.length,this.bytes=t,this.view=new DataView(t.buffer)}concat(t){let e=new I(this.size+t.size);return e.bytes.set(this.bytes,0),e.bytes.set(t.bytes,this.size),e}slice(t,e){let s=this.bytes.slice(t,e);return new I(s)}}class b{static min_size=5;constructor({type:t,stream_id:e,payload:s,payload_bytes:r}){this.type=t,this.stream_id=e,this.payload_bytes=r,this.payload=s}static parse(t){return new b({type:t.view.getUint8(0),stream_id:t.view.getUint32(1,!0),payload_bytes:t.slice(5)})}static parse_all(t){if(t.size<b.min_size)throw"packet too small";let e=b.parse(t),s=R[e.type];if(void 0===s)throw"invalid packet type";if(e.payload_bytes.size<s.size)throw"payload too small";return e.payload=s.parse(e.payload_bytes),e}serialize(){let t=new I(5);return t.view.setUint8(0,this.type),t.view.setUint32(1,this.stream_id,!0),t=t.concat(this.payload.serialize()),t}}class P{static min_size=3;static type=1;static name="CONNECT";constructor({stream_type:t,port:e,hostname:s}){this.stream_type=t,this.port=e,this.hostname=s}static parse(t){return new P({stream_type:t.view.getUint8(0),port:t.view.getUint16(1,!0),hostname:k(t.slice(3).bytes)})}serialize(){let t=new I(3);return t.view.setUint8(0,this.stream_type),t.view.setUint16(1,this.port,!0),t=t.concat(new I(this.hostname)),t}}class ${static min_size=0;static type=2;static name="DATA";constructor({data:t}){this.data=t}static parse(t){return new $({data:t})}serialize(){return this.data}}class z{static type=3;static name="CONTINUE";constructor({buffer_remaining:t}){this.buffer_remaining=t}static parse(t){return new z({buffer_remaining:t.view.getUint32(0,!0)})}serialize(){let t=new I(4);return t.view.setUint32(0,this.buffer_remaining,!0),t}}class C{static min_size=1;static type=4;static name="CLOSE";constructor({reason:t}){this.reason=t}static parse(t){return new C({reason:t.view.getUint8(0)})}serialize(){let t=new I(1);return t.view.setUint8(0,this.buffer_remaining),t}}const R=[void 0,P,$,z,C],E={CONNECT:1,DATA:2,CONTINUE:3,CLOSE:4},x={TCP:1,UDP:2},D={Unknown:1,Voluntary:2,NetworkError:3,InvalidInfo:65,UnreachableHost:66,NoResponse:67,ConnRefused:68,TransferTimeout:71,HostBlocked:72,ConnThrottled:73,ClientError:129},S={hostname_blacklist:null,hostname_whitelist:null,port_blacklist:null,port_whitelist:null,allow_direct_ip:!0,allow_private_ips:!1,allow_loopback_ips:!1,client_ip_blacklist:null,client_ip_whitelist:null,stream_limit_per_host:-1,stream_limit_total:-1,allow_udp_streams:!0,allow_tcp_streams:!0,dns_ttl:120},A=globalThis.WebSocket,O=globalThis.crypto,T=null,U=null,N=null;class M{send_buffer_size=33554432;constructor(t){this.ws=t,this.connected=!1,this.data_queue=new q(1)}async connect(){await new Promise(((t,e)=>{this.ws.onopen=()=>{this.connected=!0,t()},this.ws.onmessage=t=>{this.data_queue.put(t.data)},this.ws.onclose=()=>{this.connected?this.data_queue.close():e()},this.ws.readyState===this.ws.OPEN&&(this.connected=!0,t())}))}async recv(){return await this.data_queue.get()}async send(t){if(this.ws.send(t),!(this.ws.bufferedAmount<=this.send_buffer_size))for(;!(this.ws.bufferedAmount<=this.send_buffer_size/2);)await new Promise((t=>{setTimeout(t,10)}))}close(t,e){this.ws.close(t,e),this.data_queue.close()}get buffered_amount(){return this.ws.bufferedAmount}}class q{constructor(t){this.max_size=t,this.queue=[],this.put_callbacks=[],this.get_callbacks=[]}put_now(t){this.queue.push(t),this.get_callbacks.shift()?.()}async put(t){this.size<=this.max_size||await new Promise((t=>{this.put_callbacks.push(t)})),this.put_now(t)}get_now(){return this.put_callbacks.shift()?.(),this.queue.shift()}async get(){return this.size>0||await new Promise((t=>{this.get_callbacks.push(t)})),this.get_now()}close(){let t;for(this.queue=[];t=this.get_callbacks.shift();)t();for(;t=this.put_callbacks.shift();)t()}get size(){return this.queue.length}}const B="undefined"!=typeof process,V=new Map;function F(){if(!B)throw"not running on node.js"}async function j(t){if(!B)return t;let e=T.isIP(t);if(4===e||6===e)return t;let s=Date.now();for(let[t,e]of V)s-e.time>S.dns_ttl&&V.delete(t);let r,n=V.get(t);if(n){if(n.error)throw n.error;return n.address}try{r=(await U.lookup(t)).address,V.set(t,{time:Date.now(),address:r})}catch(e){throw V.set(t,{time:Date.now(),error:e}),e}return r}class L{constructor(t,e){F(),this.hostname=t,this.port=e,this.recv_buffer_size=128,this.socket=null,this.paused=!1,this.connected=!1,this.data_queue=new q(this.recv_buffer_size)}async connect(){let t=await j(this.hostname);await new Promise(((e,s)=>{this.socket=new T.Socket,this.socket.setNoDelay(!0),this.socket.on("connect",(()=>{this.connected=!0,e()})),this.socket.on("data",(t=>{this.data_queue.put(t)})),this.socket.on("close",(t=>{t&&!this.connected?s():this.data_queue.close(),this.socket=null})),this.socket.on("error",(t=>{_(`tcp stream to ${this.hostname} ended with error - ${t}`)})),this.socket.on("end",(()=>{this.socket&&(this.socket.destroy(),this.socket=null)})),this.socket.connect({host:t,port:this.port})}))}async recv(){return await this.data_queue.get()}async send(t){await new Promise((e=>{this.socket.write(t,e)}))}async close(){this.socket&&(this.socket.end(),this.socket=null)}pause(){this.data_queue.size>=this.data_queue.max_size&&(this.socket.pause(),this.paused=!0)}resume(){this.socket&&this.paused&&(this.socket.resume(),this.paused=!1)}}class H{constructor(t,e){F(),this.hostname=t,this.port=e,this.connected=!1,this.recv_buffer_size=128,this.data_queue=new q(this.recv_buffer_size)}async connect(){let t=await j(this.hostname),e=T.isIP(t);await new Promise(((s,r)=>{this.socket=null.createSocket(6===e?"udp6":"udp4"),this.socket.on("connect",(()=>{s()})),this.socket.on("message",(t=>{this.data_queue.put(t)})),this.socket.on("error",(()=>{this.connected||r(),this.data_queue.close(),this.socket=null})),this.socket.connect(this.port,t)}))}async recv(){return await this.data_queue.get()}async send(t){this.socket.send(t)}async close(){this.socket&&(this.socket.close(),this.socket=null)}pause(){}resume(){}}var W=s(512);class G extends Error{}function J(t,e){return t===e||t[0]<=e&&t[1]>=e}function K(t,e){let s=!1;for(let r of t)if(e(r)){s=!0;break}return!s}function Q(t,e){for(let s of t)if(e(s))return!0;return!1}function X(t,e){return e.includes(t.range())}async function Y(t,e,s,r){if(!S.allow_tcp_streams&&e===x.TCP)return D.HostBlocked;if(!S.allow_udp_streams&&e===x.UDP)return D.HostBlocked;if(S.hostname_whitelist){if(K(S.hostname_whitelist,(t=>t.test(s))))return D.HostBlocked}else if(S.hostname_blacklist&&Q(S.hostname_blacklist,(t=>t.test(s))))return D.HostBlocked;if(S.port_whitelist){if(K(S.port_whitelist,(t=>J(t,r))))return D.HostBlocked}else if(S.port_blacklist&&Q(S.port_blacklist,(t=>J(t,r))))return D.HostBlocked;let n=s;if(W.isValid(s)){if(!S.allow_direct_ip)return D.HostBlocked}else try{n=await j(s)}catch{}if(function(t){if(!W.isValid(t))return!1;let e=W.parse(t);return!(S.allow_loopback_ips||!X(e,["loopback","unspecified"]))||!(S.allow_private_ips||!X(e,["broadcast","linkLocal","carrierGradeNat","private","reserved"]))}(n))return D.HostBlocked;if(!t)return 0;if(-1!==S.stream_limit_total&&Object.keys(t.streams).length>=S.stream_limit_total)return D.ConnThrottled;if(-1!==S.stream_limit_per_host){let e=0;for(let r of t.streams)r.socket.hostname===s&&e++;if(e>=S.stream_limit_per_host)return D.ConnThrottled}return 0}class Z{static buffer_size=128;constructor(t,e,s){this.stream_id=t,this.conn=e,this.socket=s,this.send_buffer=new q(Z.buffer_size),this.packets_sent=0}async setup(){await this.socket.connect(),this.tcp_to_ws().catch((t=>{y(`(${this.conn.conn_id}) a tcp/udp to ws task encountered an error - ${t}`),this.close()})),this.ws_to_tcp().catch((t=>{y(`(${this.conn.conn_id}) a ws to tcp/udp task encountered an error - ${t}`),this.close()}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause();let e=new b({type:$.type,stream_id:this.stream_id,payload:new $({data:new I(new Uint8Array(t))})});await this.conn.ws.send(e.serialize().bytes),this.socket.resume()}await this.conn.close_stream(this.stream_id,D.Voluntary)}async ws_to_tcp(){for(;;){let t=await this.send_buffer.get();if(null==t)break;if(await this.socket.send(t),this.packets_sent++,this.packets_sent%(Z.buffer_size/2)!=0)continue;let e=new b({type:z.type,stream_id:this.stream_id,payload:new z({buffer_remaining:Z.buffer_size-this.send_buffer.size})});this.conn.ws.send(e.serialize().bytes)}await this.close()}async close(t=null){if(this.send_buffer.close(),this.socket.close(),null==t)return;let e=new b({type:C.type,stream_id:this.stream_id,payload:new C({reason:t})});await this.conn.ws.send(e.serialize().bytes)}async put_data(t){await this.send_buffer.put(t)}}class tt{constructor(t,e,{TCPSocket:s,UDPSocket:r,ping_interval:n}={}){this.ws=new M(t),this.path=e,this.TCPSocket=s||L,this.UDPSocket=r||H,this.ping_interval=n||30,this.ping_task=null,this.streams={},this.conn_id=O.randomUUID().split("-")[0]}async setup(){f(`setting up new wisp connection with id ${this.conn_id}`),await this.ws.connect();let t=new b({type:z.type,stream_id:0,payload:new z({buffer_remaining:Z.buffer_size})});await this.ws.send(t.serialize().bytes),"function"==typeof this.ws.ws.ping&&(this.ping_task=setInterval((()=>{d(`(${this.conn_id}) sending websocket ping`),this.ws.ws.ping()}),1e3*this.ping_interval))}create_stream(t,e,s,r){let n=new(e===x.TCP?this.TCPSocket:this.UDPSocket)(s,r),i=new Z(t,this,n);this.streams[t]=i,(async()=>{let n=await Y(this,e,s,r);if(n)return _(`(${this.conn_id}) refusing to create a stream to ${s}:${r}`),void await this.close_stream(t,n,!0);try{await i.setup()}catch(e){_(`(${this.conn_id}) creating a stream to ${s}:${r} failed - ${e}`),await this.close_stream(t,D.NetworkError)}})()}async close_stream(t,e=null,s=!1){let r=this.streams[t];null!=r&&(e&&!s&&f(`(${this.conn_id}) closing stream to ${r.socket.hostname} for reason ${e}`),await r.close(e),delete this.streams[t])}route_packet(t){let e=b.parse_all(t),s=this.streams[e.stream_id];if(null!=s||e.type!=$.type)if(e.type===P.type){let t=e.payload.stream_type===x.TCP?"TCP":"UDP";f(`(${this.conn_id}) opening new ${t} stream to ${e.payload.hostname}:${e.payload.port}`),this.create_stream(e.stream_id,e.payload.stream_type,e.payload.hostname.trim(),e.payload.port)}else e.type===$.type?s.put_data(e.payload.data.bytes):e.type==z.type?_(`(${this.conn_id}) client sent a CONTINUE packet, this should never be possible`):e.type==C.type&&this.close_stream(e.stream_id,e.reason);else _(`(${this.conn_id}) received a DATA packet for a stream which doesn't exist`)}async run(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;try{this.route_packet(new I(new Uint8Array(t)))}catch(t){_(`(${this.conn_id}) routing a packet failed - ${t}`)}}for(let t of Object.keys(this.streams))await this.close_stream(t);clearInterval(this.ping_task),f(`(${this.conn_id}) wisp connection closed`)}}class et{constructor(t,e){let[s,r]=e.split("/").pop().split(":");this.hostname=s.trim(),this.port=parseInt(r),this.ws=new M(t)}async setup(){if(await this.ws.connect(),0!==await Y(null,x.TCP,this.hostname,this.port))throw f(`Refusing to create a wsproxy connection to ${this.hostname}:${this.port}`),this.ws.close(),new G;this.socket=new L(this.hostname,this.port),await this.socket.connect(),this.tcp_to_ws().catch((t=>{y(`a tcp to ws task (wsproxy) encountered an error - ${t}`)})),this.ws_to_tcp().catch((t=>{y(`a ws to tcp task (wsproxy) encountered an error - ${t}`)}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause(),await this.ws.send(t),this.socket.resume()}await this.ws.close()}async ws_to_tcp(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;await this.socket.send(t)}await this.socket.close()}}let st=null;function rt(t,e,s,r={}){F(),t instanceof N.IncomingMessage?st.handleUpgrade(t,e,s,(e=>{nt(e,t.url,t,r)})):t instanceof A&&nt(ws,"/",{})}async function nt(t,e,s,r){f(`new connection on ${e} from ${s.socket.address().address}`);try{if(e.endsWith("/")){let s=new tt(t,e,r);await s.setup(),await s.run()}else{let s=new et(t,e,r);await s.setup()}}catch(e){if(t.close(),e instanceof G)return;y("Uncaught server error:\n"+e.stack)}}B&&(st=new null({noServer:!0}))})(),wisp_server=r})(); | ||
var wisp_server;(()=>{var t={512:function(t){!function(e){"use strict";const s="(0?\\d+|0x[a-f0-9]+)",r={fourOctet:new RegExp(`^${s}\\.${s}\\.${s}\\.${s}$`,"i"),threeOctet:new RegExp(`^${s}\\.${s}\\.${s}$`,"i"),twoOctet:new RegExp(`^${s}\\.${s}$`,"i"),longValue:new RegExp(`^${s}$`,"i")},n=new RegExp("^0[0-7]+$","i"),i=new RegExp("^0x[a-f0-9]+$","i"),o="%[0-9a-z]{1,}",a="(?:[0-9a-f]+::?)+",c={zoneIndex:new RegExp(o,"i"),native:new RegExp(`^(::)?(${a})?([0-9a-f]+)?(::)?(${o})?$`,"i"),deprecatedTransitional:new RegExp(`^(?:::)(${s}\\.${s}\\.${s}\\.${s}(${o})?)$`,"i"),transitional:new RegExp(`^((?:${a})|(?:::)(?:${a})?)${s}\\.${s}\\.${s}\\.${s}(${o})?$`,"i")};function l(t,e){if(t.indexOf("::")!==t.lastIndexOf("::"))return null;let s,r,n=0,i=-1,o=(t.match(c.zoneIndex)||[])[0];for(o&&(o=o.substring(1),t=t.replace(/%.+$/,""));(i=t.indexOf(":",i+1))>=0;)n++;if("::"===t.substr(0,2)&&n--,"::"===t.substr(-2,2)&&n--,n>e)return null;for(r=e-n,s=":";r--;)s+="0:";return":"===(t=t.replace("::",s))[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),{parts:e=function(){const e=t.split(":"),s=[];for(let t=0;t<e.length;t++)s.push(parseInt(e[t],16));return s}(),zoneId:o}}function h(t,e,s,r){if(t.length!==e.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");let n,i=0;for(;r>0;){if(n=s-r,n<0&&(n=0),t[i]>>n!=e[i]>>n)return!1;r-=s,i+=1}return!0}function u(t){if(i.test(t))return parseInt(t,16);if("0"===t[0]&&!isNaN(parseInt(t[1],10))){if(n.test(t))return parseInt(t,8);throw new Error(`ipaddr: cannot parse ${t} as octal`)}return parseInt(t,10)}function p(t,e){for(;t.length<e;)t=`0${t}`;return t}const d={};d.IPv4=function(){function t(t){if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");let e,s;for(e=0;e<t.length;e++)if(s=t[e],!(0<=s&&s<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=t}return t.prototype.SpecialRanges={unspecified:[[new t([0,0,0,0]),8]],broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],carrierGradeNat:[[new t([100,64,0,0]),10]],private:[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,18,0,0]),15],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]],as112:[[new t([192,175,48,0]),24],[new t([192,31,196,0]),24]],amt:[[new t([192,52,193,0]),24]]},t.prototype.kind=function(){return"ipv4"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return h(this.octets,t.octets,8,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0};let r,n,i;for(r=3;r>=0;r-=1){if(n=this.octets[r],!(n in s))return null;if(i=s[n],e&&0!==i)return null;8!==i&&(e=!0),t+=i}return 32-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.toIPv4MappedAddress=function(){return d.IPv6.parse(`::ffff:${this.toString()}`)},t.prototype.toNormalizedString=function(){return this.toString()},t.prototype.toString=function(){return this.octets.join(".")},t}(),d.IPv4.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[];let i=0;for(;i<4;)n.push(parseInt(s[i],10)|255^parseInt(r[i],10)),i++;return new this(n)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.isIPv4=function(t){return null!==this.parser(t)},d.IPv4.isValid=function(t){try{return new this(this.parser(t)),!0}catch(t){return!1}},d.IPv4.isValidCIDR=function(t){try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv4.isValidFourPartDecimal=function(t){return!(!d.IPv4.isValid(t)||!t.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/))},d.IPv4.networkAddressFromCIDR=function(t){let e,s,r,n,i;try{for(e=this.parseCIDR(t),r=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[],s=0;s<4;)n.push(parseInt(r[s],10)&parseInt(i[s],10)),s++;return new this(n)}catch(t){throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},d.IPv4.parse=function(t){const e=this.parser(t);if(null===e)throw new Error("ipaddr: string is not formatted like an IPv4 Address");return new this(e)},d.IPv4.parseCIDR=function(t){let e;if(e=t.match(/^(.+)\/(\d+)$/)){const t=parseInt(e[2]);if(t>=0&&t<=32){const s=[this.parse(e[1]),t];return Object.defineProperty(s,"toString",{value:function(){return this.join("/")}}),s}}throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},d.IPv4.parser=function(t){let e,s,n;if(e=t.match(r.fourOctet))return function(){const t=e.slice(1,6),r=[];for(let e=0;e<t.length;e++)s=t[e],r.push(u(s));return r}();if(e=t.match(r.longValue)){if(n=u(e[1]),n>4294967295||n<0)throw new Error("ipaddr: address outside defined range");return function(){const t=[];let e;for(e=0;e<=24;e+=8)t.push(n>>e&255);return t}().reverse()}return(e=t.match(r.twoOctet))?function(){const t=e.slice(1,4),s=[];if(n=u(t[1]),n>16777215||n<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(n>>16&255),s.push(n>>8&255),s.push(255&n),s}():(e=t.match(r.threeOctet))?function(){const t=e.slice(1,5),s=[];if(n=u(t[2]),n>65535||n<0)throw new Error("ipaddr: address outside defined range");return s.push(u(t[0])),s.push(u(t[1])),s.push(n>>8&255),s.push(255&n),s}():null},d.IPv4.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>32)throw new Error("ipaddr: invalid IPv4 prefix length");const e=[0,0,0,0];let s=0;const r=Math.floor(t/8);for(;s<r;)e[s]=255,s++;return r<4&&(e[r]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.IPv6=function(){function t(t,e){let s,r;if(16===t.length)for(this.parts=[],s=0;s<=14;s+=2)this.parts.push(t[s]<<8|t[s+1]);else{if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=t}for(s=0;s<this.parts.length;s++)if(r=this.parts[s],!(0<=r&&r<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits");e&&(this.zoneId=e)}return t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],discard:[new t([256,0,0,0,0,0,0,0]),64],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],benchmarking:[new t([8193,2,0,0,0,0,0,0]),48],amt:[new t([8193,3,0,0,0,0,0,0]),32],as112v6:[[new t([8193,4,274,0,0,0,0,0]),48],[new t([9760,79,32768,0,0,0,0,0]),48]],deprecated:[new t([8193,16,0,0,0,0,0,0]),28],orchid2:[new t([8193,32,0,0,0,0,0,0]),28],droneRemoteIdProtocolEntityTags:[new t([8193,48,0,0,0,0,0,0]),28],reserved:[[new t([8193,0,0,0,0,0,0,0]),23],[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.kind=function(){return"ipv6"},t.prototype.match=function(t,e){let s;if(void 0===e&&(s=t,t=s[0],e=s[1]),"ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return h(this.parts,t.parts,16,e)},t.prototype.prefixLengthFromSubnetMask=function(){let t=0,e=!1;const s={0:16,32768:15,49152:14,57344:13,61440:12,63488:11,64512:10,65024:9,65280:8,65408:7,65472:6,65504:5,65520:4,65528:3,65532:2,65534:1,65535:0};let r,n;for(let i=7;i>=0;i-=1){if(r=this.parts[i],!(r in s))return null;if(n=s[r],e&&0!==n)return null;16!==n&&(e=!0),t+=n}return 128-t},t.prototype.range=function(){return d.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){let t;const e=[],s=this.parts;for(let r=0;r<s.length;r++)t=s[r],e.push(t>>8),e.push(255&t);return e},t.prototype.toFixedLengthString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(p(this.parts[e].toString(16),4));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toIPv4Address=function(){if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");const t=this.parts.slice(-2),e=t[0],s=t[1];return new d.IPv4([e>>8,255&e,s>>8,255&s])},t.prototype.toNormalizedString=function(){const t=function(){const t=[];for(let e=0;e<this.parts.length;e++)t.push(this.parts[e].toString(16));return t}.call(this).join(":");let e="";return this.zoneId&&(e=`%${this.zoneId}`),t+e},t.prototype.toRFC5952String=function(){const t=/((^|:)(0(:|$)){2,})/g,e=this.toNormalizedString();let s,r=0,n=-1;for(;s=t.exec(e);)s[0].length>n&&(r=s.index,n=s[0].length);return n<0?e:`${e.substring(0,r)}::${e.substring(r+n)}`},t.prototype.toString=function(){return this.toRFC5952String()},t}(),d.IPv6.broadcastAddressFromCIDR=function(t){try{const e=this.parseCIDR(t),s=e[0].toByteArray(),r=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[];let i=0;for(;i<16;)n.push(parseInt(s[i],10)|255^parseInt(r[i],10)),i++;return new this(n)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.isIPv6=function(t){return null!==this.parser(t)},d.IPv6.isValid=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{const e=this.parser(t);return new this(e.parts,e.zoneId),!0}catch(t){return!1}},d.IPv6.isValidCIDR=function(t){if("string"==typeof t&&-1===t.indexOf(":"))return!1;try{return this.parseCIDR(t),!0}catch(t){return!1}},d.IPv6.networkAddressFromCIDR=function(t){let e,s,r,n,i;try{for(e=this.parseCIDR(t),r=e[0].toByteArray(),i=this.subnetMaskFromPrefixLength(e[1]).toByteArray(),n=[],s=0;s<16;)n.push(parseInt(r[s],10)&parseInt(i[s],10)),s++;return new this(n)}catch(t){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${t})`)}},d.IPv6.parse=function(t){const e=this.parser(t);if(null===e.parts)throw new Error("ipaddr: string is not formatted like an IPv6 Address");return new this(e.parts,e.zoneId)},d.IPv6.parseCIDR=function(t){let e,s,r;if((s=t.match(/^(.+)\/(\d+)$/))&&(e=parseInt(s[2]),e>=0&&e<=128))return r=[this.parse(s[1]),e],Object.defineProperty(r,"toString",{value:function(){return this.join("/")}}),r;throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},d.IPv6.parser=function(t){let e,s,r,n,i,o;if(r=t.match(c.deprecatedTransitional))return this.parser(`::ffff:${r[1]}`);if(c.native.test(t))return l(t,8);if((r=t.match(c.transitional))&&(o=r[6]||"",e=r[1],r[1].endsWith("::")||(e=e.slice(0,-1)),e=l(e+o,6),e.parts)){for(i=[parseInt(r[2]),parseInt(r[3]),parseInt(r[4]),parseInt(r[5])],s=0;s<i.length;s++)if(n=i[s],!(0<=n&&n<=255))return null;return e.parts.push(i[0]<<8|i[1]),e.parts.push(i[2]<<8|i[3]),{parts:e.parts,zoneId:e.zoneId}}return null},d.IPv6.subnetMaskFromPrefixLength=function(t){if((t=parseInt(t))<0||t>128)throw new Error("ipaddr: invalid IPv6 prefix length");const e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];let s=0;const r=Math.floor(t/8);for(;s<r;)e[s]=255,s++;return r<16&&(e[r]=Math.pow(2,t%8)-1<<8-t%8),new this(e)},d.fromByteArray=function(t){const e=t.length;if(4===e)return new d.IPv4(t);if(16===e)return new d.IPv6(t);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},d.isValid=function(t){return d.IPv6.isValid(t)||d.IPv4.isValid(t)},d.isValidCIDR=function(t){return d.IPv6.isValidCIDR(t)||d.IPv4.isValidCIDR(t)},d.parse=function(t){if(d.IPv6.isValid(t))return d.IPv6.parse(t);if(d.IPv4.isValid(t))return d.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},d.parseCIDR=function(t){try{return d.IPv6.parseCIDR(t)}catch(e){try{return d.IPv4.parseCIDR(t)}catch(t){throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},d.process=function(t){const e=this.parse(t);return"ipv6"===e.kind()&&e.isIPv4MappedAddress()?e.toIPv4Address():e},d.subnetMatch=function(t,e,s){let r,n,i,o;for(n in null==s&&(s="unicast"),e)if(Object.prototype.hasOwnProperty.call(e,n))for(i=e[n],!i[0]||i[0]instanceof Array||(i=[i]),r=0;r<i.length;r++)if(o=i[r],t.kind()===o[0].kind()&&t.match.apply(t,o))return n;return s},t.exports?t.exports=d:e.ipaddr=d}(this)}},e={};function s(r){var n=e[r];if(void 0!==n)return n.exports;var i=e[r]={exports:{}};return t[r].call(i.exports,i,i.exports,s),i.exports}s.d=(t,e)=>{for(var r in e)s.o(e,r)&&!s.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};(()=>{"use strict";s.r(r),s.d(r,{logging:()=>t,packet:()=>e,server:()=>n});var t={};s.r(t),s.d(t,{DEBUG:()=>i,ERROR:()=>c,INFO:()=>o,NONE:()=>l,WARN:()=>a,debug:()=>d,error:()=>y,get_timestamp:()=>u,info:()=>f,log:()=>w,log_level:()=>h,set_level:()=>p,warn:()=>_});var e={};s.r(e),s.d(e,{ClosePayload:()=>C,ConnectPayload:()=>P,ContinuePayload:()=>z,DataPayload:()=>$,WispBuffer:()=>I,WispPacket:()=>b,close_reasons:()=>x,packet_classes:()=>E,packet_types:()=>R,stream_types:()=>D});var n={};s.r(n),s.d(n,{ServerConnection:()=>it,ServerStream:()=>nt,options:()=>S,routeRequest:()=>ct});const i=0,o=1,a=2,c=3,l=4;let h=o;function u(){let[t,e]=(new Date).toJSON().split("T");return t=t.replaceAll("-","/"),e=e.split(".")[0],`[${t} - ${e}]`}function p(t){h=t}function d(...t){h>i||console.debug(u()+" debug:",...t)}function f(...t){h>o||console.info(u()+" info:",...t)}function w(...t){h>o||console.log(u()+" log:",...t)}function _(...t){h>a||console.warn(u()+" warn:",...t)}function y(...t){h>c||console.error(u()+" error:",...t)}const m=new TextEncoder,v=m.encode.bind(m),g=new TextDecoder,k=g.decode.bind(g);class I{constructor(t){if(t instanceof Uint8Array)this.from_array(t);else if("number"==typeof t)this.from_array(new Uint8Array(t));else{if("string"!=typeof t)throw console.trace(),"invalid data type passed to wisp buffer constructor";this.from_array(v(t))}}from_array(t){this.size=t.length,this.bytes=t,this.view=new DataView(t.buffer)}concat(t){let e=new I(this.size+t.size);return e.bytes.set(this.bytes,0),e.bytes.set(t.bytes,this.size),e}slice(t,e){let s=this.bytes.slice(t,e);return new I(s)}}class b{static min_size=5;constructor({type:t,stream_id:e,payload:s,payload_bytes:r}){this.type=t,this.stream_id=e,this.payload_bytes=r,this.payload=s}static parse(t){return new b({type:t.view.getUint8(0),stream_id:t.view.getUint32(1,!0),payload_bytes:t.slice(5)})}static parse_all(t){if(t.size<b.min_size)throw"packet too small";let e=b.parse(t),s=E[e.type];if(void 0===s)throw"invalid packet type";if(e.payload_bytes.size<s.size)throw"payload too small";return e.payload=s.parse(e.payload_bytes),e}serialize(){let t=new I(5);return t.view.setUint8(0,this.type),t.view.setUint32(1,this.stream_id,!0),t=t.concat(this.payload.serialize()),t}}class P{static min_size=3;static type=1;static name="CONNECT";constructor({stream_type:t,port:e,hostname:s}){this.stream_type=t,this.port=e,this.hostname=s}static parse(t){return new P({stream_type:t.view.getUint8(0),port:t.view.getUint16(1,!0),hostname:k(t.slice(3).bytes)})}serialize(){let t=new I(3);return t.view.setUint8(0,this.stream_type),t.view.setUint16(1,this.port,!0),t=t.concat(new I(this.hostname)),t}}class ${static min_size=0;static type=2;static name="DATA";constructor({data:t}){this.data=t}static parse(t){return new $({data:t})}serialize(){return this.data}}class z{static type=3;static name="CONTINUE";constructor({buffer_remaining:t}){this.buffer_remaining=t}static parse(t){return new z({buffer_remaining:t.view.getUint32(0,!0)})}serialize(){let t=new I(4);return t.view.setUint32(0,this.buffer_remaining,!0),t}}class C{static min_size=1;static type=4;static name="CLOSE";constructor({reason:t}){this.reason=t}static parse(t){return new C({reason:t.view.getUint8(0)})}serialize(){let t=new I(1);return t.view.setUint8(0,this.buffer_remaining),t}}const E=[void 0,P,$,z,C],R={CONNECT:1,DATA:2,CONTINUE:3,CLOSE:4},D={TCP:1,UDP:2},x={Unknown:1,Voluntary:2,NetworkError:3,InvalidInfo:65,UnreachableHost:66,NoResponse:67,ConnRefused:68,TransferTimeout:71,HostBlocked:72,ConnThrottled:73,ClientError:129},S={hostname_blacklist:null,hostname_whitelist:null,port_blacklist:null,port_whitelist:null,allow_direct_ip:!0,allow_private_ips:!1,allow_loopback_ips:!1,client_ip_blacklist:null,client_ip_whitelist:null,stream_limit_per_host:-1,stream_limit_total:-1,allow_udp_streams:!0,allow_tcp_streams:!0,dns_ttl:120,dns_method:"lookup",dns_servers:null,dns_result_order:"verbatim"},A=globalThis.WebSocket,O=globalThis.crypto,T=null,U=null,N=null;class M{send_buffer_size=33554432;constructor(t){this.ws=t,this.connected=!1,this.data_queue=new q(1)}async connect(){await new Promise(((t,e)=>{this.ws.onopen=()=>{this.connected=!0,t()},this.ws.onmessage=t=>{this.data_queue.put(t.data)},this.ws.onclose=()=>{this.connected?this.data_queue.close():e()},this.ws.readyState===this.ws.OPEN&&(this.connected=!0,t())}))}async recv(){return await this.data_queue.get()}async send(t){if(this.ws.send(t),!(this.ws.bufferedAmount<=this.send_buffer_size))for(;!(this.ws.bufferedAmount<=this.send_buffer_size/2);)await new Promise((t=>{setTimeout(t,10)}))}close(t,e){this.ws.close(t,e),this.data_queue.close()}get buffered_amount(){return this.ws.bufferedAmount}}class q{constructor(t){this.max_size=t,this.queue=[],this.put_callbacks=[],this.get_callbacks=[]}put_now(t){this.queue.push(t),this.get_callbacks.shift()?.()}async put(t){this.size<=this.max_size||await new Promise((t=>{this.put_callbacks.push(t)})),this.put_now(t)}get_now(){return this.put_callbacks.shift()?.(),this.queue.shift()}async get(){return this.size>0||await new Promise((t=>{this.get_callbacks.push(t)})),this.get_now()}close(){let t;for(this.queue=[];t=this.get_callbacks.shift();)t();for(;t=this.put_callbacks.shift();)t()}get size(){return this.queue.length}}const B="undefined"!=typeof process,V=new Map;let j=null,F=null;function L(){if(!B)throw"not running on node.js"}function H(t){return F.resolve4(t)}function W(t){return F.resolve6(t)}async function G(t,e,s){try{return(await t(s))[0]}catch{return(await e(s))[0]}}async function J(t){if(!B)return t;let e=T.isIP(t);if(4===e||6===e)return t;let s=Date.now();for(let[t,e]of V)s-e.time>S.dns_ttl&&V.delete(t);let r,n=V.get(t);if(n){if(n.error)throw n.error;return n.address}try{r=await async function(t){if("lookup"===S.dns_method)return(await U.lookup(t,{order:S.dns_result_order})).address;if("resolve"===S.dns_method){if(F||(F=new U.Resolver),S.dns_servers!==j&&(d("Setting custom DNS servers to: "+S.dns_servers.join(", ")),F.setServers(S.dns_servers),j=S.dns_servers),"verbatim"===S.dns_result_order||"ipv6first"===S.dns_result_order)return await G(W,H,t);if("ipv4first"===S.dns_result_order)return await G(H,W,t);throw new Error("Invalid result order. options.dns_result_order must be either 'ipv6first', 'ipv4first', or 'verbatim'.")}if("function"==typeof S.dns_method)return await S.dns_method(t);throw new Error("Invalid DNS method. options.dns_method must either be 'lookup' or 'resolve'.")}(t),d(`Domain resolved: ${t} -> ${r}`),V.set(t,{time:Date.now(),address:r})}catch(e){throw V.set(t,{time:Date.now(),error:e}),e}return r}class K{constructor(t,e){L(),this.hostname=t,this.port=e,this.recv_buffer_size=128,this.socket=null,this.paused=!1,this.connected=!1,this.data_queue=new q(this.recv_buffer_size)}async connect(){let t=await J(this.hostname);await new Promise(((e,s)=>{this.socket=new T.Socket,this.socket.setNoDelay(!0),this.socket.on("connect",(()=>{this.connected=!0,e()})),this.socket.on("data",(t=>{this.data_queue.put(t)})),this.socket.on("close",(t=>{t&&!this.connected?s():this.data_queue.close(),this.socket=null})),this.socket.on("error",(t=>{_(`tcp stream to ${this.hostname} ended with error - ${t}`)})),this.socket.on("end",(()=>{this.socket&&(this.socket.destroy(),this.socket=null)})),this.socket.connect({host:t,port:this.port})}))}async recv(){return await this.data_queue.get()}async send(t){await new Promise((e=>{this.socket.write(t,e)}))}async close(){this.socket&&(this.socket.end(),this.socket=null)}pause(){this.data_queue.size>=this.data_queue.max_size&&(this.socket.pause(),this.paused=!0)}resume(){this.socket&&this.paused&&(this.socket.resume(),this.paused=!1)}}class Q{constructor(t,e){L(),this.hostname=t,this.port=e,this.connected=!1,this.recv_buffer_size=128,this.data_queue=new q(this.recv_buffer_size)}async connect(){let t=await J(this.hostname),e=T.isIP(t);await new Promise(((s,r)=>{this.socket=null.createSocket(6===e?"udp6":"udp4"),this.socket.on("connect",(()=>{s()})),this.socket.on("message",(t=>{this.data_queue.put(t)})),this.socket.on("error",(()=>{this.connected||r(),this.data_queue.close(),this.socket=null})),this.socket.connect(this.port,t)}))}async recv(){return await this.data_queue.get()}async send(t){this.socket.send(t)}async close(){this.socket&&(this.socket.close(),this.socket=null)}pause(){}resume(){}}var X=s(512);class Y extends Error{}function Z(t,e){return t===e||t[0]<=e&&t[1]>=e}function tt(t,e){let s=!1;for(let r of t)if(e(r)){s=!0;break}return!s}function et(t,e){for(let s of t)if(e(s))return!0;return!1}function st(t,e){return e.includes(t.range())}async function rt(t,e,s,r){if(!S.allow_tcp_streams&&e===D.TCP)return x.HostBlocked;if(!S.allow_udp_streams&&e===D.UDP)return x.HostBlocked;if(S.hostname_whitelist){if(tt(S.hostname_whitelist,(t=>t.test(s))))return x.HostBlocked}else if(S.hostname_blacklist&&et(S.hostname_blacklist,(t=>t.test(s))))return x.HostBlocked;if(S.port_whitelist){if(tt(S.port_whitelist,(t=>Z(t,r))))return x.HostBlocked}else if(S.port_blacklist&&et(S.port_blacklist,(t=>Z(t,r))))return x.HostBlocked;let n=s;if(X.isValid(s)){if(!S.allow_direct_ip)return x.HostBlocked}else try{n=await J(s)}catch{}if(function(t){if(!X.isValid(t))return!1;let e=X.parse(t);return!(S.allow_loopback_ips||!st(e,["loopback","unspecified"]))||!(S.allow_private_ips||!st(e,["broadcast","linkLocal","carrierGradeNat","private","reserved"]))}(n))return x.HostBlocked;if(!t)return 0;if(-1!==S.stream_limit_total&&Object.keys(t.streams).length>=S.stream_limit_total)return x.ConnThrottled;if(-1!==S.stream_limit_per_host){let e=0;for(let r of t.streams)r.socket.hostname===s&&e++;if(e>=S.stream_limit_per_host)return x.ConnThrottled}return 0}class nt{static buffer_size=128;constructor(t,e,s){this.stream_id=t,this.conn=e,this.socket=s,this.send_buffer=new q(nt.buffer_size),this.packets_sent=0}async setup(){await this.socket.connect(),this.tcp_to_ws().catch((t=>{y(`(${this.conn.conn_id}) a tcp/udp to ws task encountered an error - ${t}`),this.close()})),this.ws_to_tcp().catch((t=>{y(`(${this.conn.conn_id}) a ws to tcp/udp task encountered an error - ${t}`),this.close()}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause();let e=new b({type:$.type,stream_id:this.stream_id,payload:new $({data:new I(new Uint8Array(t))})});await this.conn.ws.send(e.serialize().bytes),this.socket.resume()}await this.conn.close_stream(this.stream_id,x.Voluntary)}async ws_to_tcp(){for(;;){let t=await this.send_buffer.get();if(null==t)break;if(await this.socket.send(t),this.packets_sent++,this.packets_sent%(nt.buffer_size/2)!=0)continue;let e=new b({type:z.type,stream_id:this.stream_id,payload:new z({buffer_remaining:nt.buffer_size-this.send_buffer.size})});this.conn.ws.send(e.serialize().bytes)}await this.close()}async close(t=null){if(this.send_buffer.close(),this.socket.close(),null==t)return;let e=new b({type:C.type,stream_id:this.stream_id,payload:new C({reason:t})});await this.conn.ws.send(e.serialize().bytes)}async put_data(t){await this.send_buffer.put(t)}}class it{constructor(t,e,{TCPSocket:s,UDPSocket:r,ping_interval:n}={}){this.ws=new M(t),this.path=e,this.TCPSocket=s||K,this.UDPSocket=r||Q,this.ping_interval=n||30,this.ping_task=null,this.streams={},this.conn_id=O.randomUUID().split("-")[0]}async setup(){f(`setting up new wisp connection with id ${this.conn_id}`),await this.ws.connect();let t=new b({type:z.type,stream_id:0,payload:new z({buffer_remaining:nt.buffer_size})});await this.ws.send(t.serialize().bytes),"function"==typeof this.ws.ws.ping&&(this.ping_task=setInterval((()=>{d(`(${this.conn_id}) sending websocket ping`),this.ws.ws.ping()}),1e3*this.ping_interval))}create_stream(t,e,s,r){let n=new(e===D.TCP?this.TCPSocket:this.UDPSocket)(s,r),i=new nt(t,this,n);this.streams[t]=i,(async()=>{let n=await rt(this,e,s,r);if(n)return _(`(${this.conn_id}) refusing to create a stream to ${s}:${r}`),void await this.close_stream(t,n,!0);try{await i.setup()}catch(e){_(`(${this.conn_id}) creating a stream to ${s}:${r} failed - ${e}`),await this.close_stream(t,x.NetworkError)}})()}async close_stream(t,e=null,s=!1){let r=this.streams[t];null!=r&&(e&&!s&&f(`(${this.conn_id}) closing stream to ${r.socket.hostname} for reason ${e}`),await r.close(e),delete this.streams[t])}route_packet(t){let e=b.parse_all(t),s=this.streams[e.stream_id];if(null!=s||e.type!=$.type)if(e.type===P.type){let t=e.payload.stream_type===D.TCP?"TCP":"UDP";f(`(${this.conn_id}) opening new ${t} stream to ${e.payload.hostname}:${e.payload.port}`),this.create_stream(e.stream_id,e.payload.stream_type,e.payload.hostname.trim(),e.payload.port)}else e.type===$.type?s.put_data(e.payload.data.bytes):e.type==z.type?_(`(${this.conn_id}) client sent a CONTINUE packet, this should never be possible`):e.type==C.type&&this.close_stream(e.stream_id,e.reason);else _(`(${this.conn_id}) received a DATA packet for a stream which doesn't exist`)}async run(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;try{this.route_packet(new I(new Uint8Array(t)))}catch(t){_(`(${this.conn_id}) routing a packet failed - ${t}`)}}for(let t of Object.keys(this.streams))await this.close_stream(t);clearInterval(this.ping_task),f(`(${this.conn_id}) wisp connection closed`)}}class ot{constructor(t,e){let[s,r]=e.split("/").pop().split(":");this.hostname=s.trim(),this.port=parseInt(r),this.ws=new M(t)}async setup(){if(await this.ws.connect(),0!==await rt(null,D.TCP,this.hostname,this.port))throw f(`Refusing to create a wsproxy connection to ${this.hostname}:${this.port}`),this.ws.close(),new Y;this.socket=new K(this.hostname,this.port),await this.socket.connect(),this.tcp_to_ws().catch((t=>{y(`a tcp to ws task (wsproxy) encountered an error - ${t}`)})),this.ws_to_tcp().catch((t=>{y(`a ws to tcp task (wsproxy) encountered an error - ${t}`)}))}async tcp_to_ws(){for(;;){let t=await this.socket.recv();if(null==t)break;this.socket.pause(),await this.ws.send(t),this.socket.resume()}await this.ws.close()}async ws_to_tcp(){for(;;){let t;if(t=await this.ws.recv(),null==t)break;await this.socket.send(t)}await this.socket.close()}}let at=null;function ct(t,e,s,r={}){L(),t instanceof N.IncomingMessage?at.handleUpgrade(t,e,s,(e=>{lt(e,t.url,t,r)})):t instanceof A&<(ws,"/",{})}async function lt(t,e,s,r){f(`new connection on ${e} from ${s.socket.address().address}`);try{if(e.endsWith("/")){let s=new it(t,e,r);await s.setup(),await s.run()}else{let s=new ot(t,e,r);await s.setup()}}catch(e){if(t.close(),e instanceof Y)return;y("Uncaught server error:\n"+e.stack)}}B&&(at=new null({noServer:!0}))})(),wisp_server=r})(); |
{ | ||
"name": "@mercuryworkshop/wisp-js", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "A client and server for the Wisp protocol, written in Javascript", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -176,5 +176,5 @@ # JavaScript Wisp Implementation | ||
### Changing Server Settings: | ||
To change settings globally for the Wisp server, you can use the `wisp.options` object. | ||
To change settings globally for the Wisp server, you can use the `wisp.options` object. Here is a list of all of the available settings: | ||
The available settings are: | ||
**Blacklist / Whitelist Options:** | ||
- `options.hostname_blacklist` - An array of regex objects to match against the destination server. Any matches will be blocked. | ||
@@ -184,2 +184,4 @@ - `options.hostname_whitelist` - Same as `hostname_blacklist`, but only matches will be allowed through, and setting this will supersede `hostname_blacklist`. | ||
- `options.port_whitelist` - Same as `port_whitelist`, but only matches will be allowed through, and setting this will supersede `port_blacklist`. | ||
**Stream Restrictions:** | ||
- `options.stream_limit_per_host` - The maximum number of streams that may be open to a single hostname, per connection. Defaults to no limit. | ||
@@ -189,2 +191,4 @@ - `options.stream_limit_total` - The total number of streams that may be open to all hosts combined, per connection. Defaults to no limit. | ||
- `options.allow_tcp_streams` - If this is `false`, TCP streams will be blocked. Defaults to `true`. | ||
**IP Restrictions:** | ||
- `options.allow_direct_ip` - Allow connections directly to IP addresses, which bypasses the server-side DNS resolution. Turning this off allows the server administrator to enforce a block list more effectively. Defaults to `true`. | ||
@@ -194,2 +198,8 @@ - `options.allow_private_ips` - Allow connections to private IP addresses. Defaults to `false`. | ||
**DNS Settings:** | ||
- `options.dns_ttl` - The time to live for cached DNS responses, in seconds. Defaults to `120` seconds. | ||
- `options.dns_method` - The method to use for DNS resolution. This is either `"lookup"`, which uses the system DNS, or `"resolve"`, which uses the Node `dns.resolve` functions. This may also be a custom async function, which takes the hostname as its only argument and returns the resolved IP address. Defaults to `"lookup"`. | ||
- `options.dns_servers` - A [list of strings containing IP addresses](https://nodejs.org/api/dns.html#dnspromisessetserversservers) for custom DNS servers. This is only used if `dns_method` is set to `"resolve"`. By default, this is unset, and DNS queries will use the system DNS servers. | ||
- `options.dns_result_order` - Controls whether or not IPv4 or IPv6 addresses are prioritized. This can be either `"ipv4first"`, `"ipv6first"`, or `"verbatim"`. `"verbatim"` uses the original order that the system DNS returns the results in, and only has special meaning if the DNS method is `"lookup"`. If the DNS method is `"resolve"`, `"verbatim"` is treated the same as `"ipv6first"`. Defaults to `"verbatim"`. | ||
For example: | ||
@@ -207,2 +217,7 @@ ```js | ||
``` | ||
```js | ||
wisp.options.dns_method = "resolve"; | ||
wisp.options.dns_servers = ["1.1.1.3", "1.0.0.3"]; | ||
wisp.options.dns_result_order = "ipv4first"; | ||
``` | ||
@@ -209,0 +224,0 @@ ## Copyright: |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
295419
1380
239