@@ -182,6 +182,55 @@ func (cr *CommandRunner) handleInternalCmd() (int, string) {
182182 }
183183
184184 return 0 , "Spawned a ftp terminal."
185+ case "opentunnel" :
186+ log .Debug ().
187+ Str ("sessionID" , cr .data .SessionID ).
188+ Int ("targetPort" , cr .data .TargetPort ).
189+ Str ("url" , cr .data .URL ).
190+ Msg ("Received opentunnel command" )
191+
192+ // Validate port range (1-65535, 0 is reserved)
193+ if cr .data .TargetPort < 1 || cr .data .TargetPort > 65535 {
194+ return 1 , fmt .Sprintf ("opentunnel: Invalid target port %d. Must be between 1 and 65535." , cr .data .TargetPort )
195+ }
196+
197+ data := openTunnelData {
198+ SessionID : cr .data .SessionID ,
199+ TargetPort : cr .data .TargetPort ,
200+ URL : cr .data .URL ,
201+ }
202+ err := cr .validateData (data )
203+ if err != nil {
204+ return 1 , fmt .Sprintf ("opentunnel: Not enough information. %s" , err .Error ())
205+ }
206+
207+ // Check if tunnel already exists
208+ if _ , exists := GetActiveTunnel (cr .data .SessionID ); exists {
209+ return 1 , fmt .Sprintf ("opentunnel: Tunnel session %s already exists." , cr .data .SessionID )
210+ }
211+
212+ tunnelClient := NewTunnelClient (
213+ cr .data .SessionID ,
214+ cr .data .TargetPort ,
215+ cr .data .URL ,
216+ )
217+ go tunnelClient .RunTunnelBackground ()
218+
219+ return 0 , fmt .Sprintf ("Spawned a tunnel for session %s, target port %d." , cr .data .SessionID , cr .data .TargetPort )
220+ case "closetunnel" :
221+ data := closeTunnelData {
222+ SessionID : cr .data .SessionID ,
223+ }
224+ err := cr .validateData (data )
225+ if err != nil {
226+ return 1 , fmt .Sprintf ("closetunnel: Not enough information. %s" , err .Error ())
227+ }
228+
229+ if err := CloseTunnel (cr .data .SessionID ); err != nil {
230+ return 1 , fmt .Sprintf ("closetunnel: %s" , err .Error ())
231+ }
232+
233+ return 0 , fmt .Sprintf ("Closed tunnel session %s." , cr .data .SessionID )
185234 case "resizepty" :
186235 if terminals [cr .data .SessionID ] != nil {
187236 err := terminals [cr .data .SessionID ].resize (cr .data .Rows , cr .data .Cols )
0 commit comments