1+ const { spawn } = require ( 'node:child_process' ) ;
2+
3+ // Configuration
4+ let serverPort = process . env . PORT || process . env . serverPort || 3000 ;
5+ const filterLinks = [ "https://dashboard.pinggy.io" , "https://pinggy.io" ] ;
6+ const maxPinggy = 10 ; // Total concurrent tunnels
7+
8+ const commandArgs = [
9+ [ 'ssh' , [
10+ '-p' , '443' ,
11+ '-o' , 'StrictHostKeyChecking=no' ,
12+ '-o' , 'ServerAliveInterval=30' ,
13+ '-R' , `0:localhost:${ serverPort } ` ,
14+ '-L' , '4300:127.0.0.1:4300' ,
15+ 'qr@free.pinggy.io'
16+ ] ]
17+ ] ;
18+
19+ var activeTunnels = new Map ( ) ;
20+ var curPinggy = 0 ;
21+
22+ function spawnTunnel ( index ) {
23+ if ( curPinggy >= maxPinggy ) return ;
24+
25+ curPinggy += 1 ;
26+ const [ cmdName , args ] = commandArgs [ index ] ;
27+ const child = spawn ( cmdName , args ) ;
28+ const pid = child . pid ;
29+
30+ child . stdout . on ( 'data' , ( data ) => {
31+ const output = data . toString ( ) ;
32+
33+ // Improved URL regex to catch URLs even if they are surrounded by ANSI codes
34+ const urlRegex = / h t t p s : \/ \/ [ ^ \s " ' < > ] + / g;
35+ const foundLinks = output . match ( urlRegex ) ;
36+
37+ if ( foundLinks ) {
38+ foundLinks . forEach ( link => {
39+ const s = link . trim ( ) . replace ( / \x1B \[ [ 0 - 9 ; ] * [ m K ] / g, "" ) ; // Clean ANSI colors
40+
41+ if ( ! filterLinks . some ( f => s . startsWith ( f ) ) && ! activeTunnels . has ( pid ) ) {
42+ activeTunnels . set ( pid , {
43+ url : s ,
44+ ts : Date . now ( )
45+ } ) ;
46+ }
47+ } ) ;
48+ }
49+ } ) ;
50+
51+ // Capture errors to help with debugging
52+ child . stderr . on ( 'data' , ( data ) => {
53+ if ( data . toString ( ) . includes ( "Permission denied" ) ) {
54+ console . error ( `[Error] PID ${ pid } check your SSH keys.` ) ;
55+ }
56+ } ) ;
57+
58+ child . on ( 'close' , ( code ) => {
59+ curPinggy -= 1 ;
60+ activeTunnels . delete ( pid ) ;
61+
62+ // Staggered restart to avoid spamming the CPU
63+ setTimeout ( ( ) => {
64+ spawnTunnel ( index ) ;
65+ } , 5000 ) ;
66+ } ) ;
67+ }
68+
69+ // Initial Boot
70+ for ( let i = 0 ; i < maxPinggy ; i ++ ) {
71+ // Distribute processes evenly across providers
72+ spawnTunnel ( i % commandArgs . length ) ;
73+ }
74+
75+ function getActiveAltLinks ( ) {
76+ return Array . from ( activeTunnels . values ( ) ) ;
77+ }
78+
79+ module . exports = { getActiveAltLinks } ;
0 commit comments