#include 'WSA_NBTCP.au3' ; Opt('TrayAutoPause', 0) Opt('MustDeclareVars', 1) OnAutoItExitRegister('ExitApp') ; LocalGatewayProxy() ; ; ; #FUNCTION# *************************************************************************************************************** ; Name..........:.LocalGatewayProxy() ; Date..........: February 07, 2018 ; Script Version: 1.00 ; AutoIt Version: v3.3.8.1+ (32Bit only) ; Released By...: ripdad ; ..............: ; Description...: A Gateway Proxy Sends and Receives Data Unmodified. ; ..............: https://en.wikipedia.org/wiki/Proxy_server ; ..............: ---------------------------------------------------------------------------------------------------------- ; Remarks.......: Use as a relay or router between two known static IP addresses. ; ..............: ; ..............: It should accept any data input from any TCP program. ; ..............: ; ..............: Web traffic should be routed to a web-proxy or web-server/web-device, ; ..............: unless the destination is a single website. ; ..............: ; ..............: If used for other than web traffic, a header or set of commands ; ..............: will be needed. You will have to devise them if they do not exist. ; ..............: ; ..............: The LocalIP must initiate a connection. ; ..............: The RemoteIP cannot initiate a connection. ; ..............: ; ..............: Flow Diagram and Abilities: ; ..............: LocalIP (Connect//Receive/Send)-> LocalGatewayProxy (Connect/Receive/Send)-> RemoteIP (Receive/Send) ; ..............: ; ..............: 1) The LocalIP and RemoteIP addresses must be static. It was not intended that they change on the fly. ; ..............: ; ..............: 2) They can each have different IP's and Port's. The LocalIP can be from another computer. ; ..............: Flow Diagram: ; ..............: NetworkComputer -> LocalGatewayProxy (your computer) -> RemoteComputer or RemoteDevice ; ..............: ; ..............: Equivalent Pseudo Code: ; ..............: Step 1: _WSA_TCPListen(LocalIP->ListenSocket) ; ..............: Step 2: _WSA_TCPAccept(ListenSocket->LocalSocket) ; ..............: Step 3: _WSA_TCPConnect(RemoteIP->RemoteSocket) ; ..............: Step 4: _WSA_TCPSend(RemoteSocket, _WSA_TCPRecv(LocalSocket)) ; ..............: Step 5: _WSA_TCPSend(LocalSocket, _WSA_TCPRecv(RemoteSocket)) ; ..............: Step 6: Go to Step 2 ; ..............: ; ..............: Simple Setup: ; ..............: Just modify the "IP and Port Settings" below to suit your needs and you are on your way. ;*************************************************************************************************************************** Func LocalGatewayProxy() Local $sTitle = 'LocalGatewayProxy v1.00' ; If Not TCPStartup() Then MsgBox(8208, $sTitle, 'Error: TCPStartup' & @TAB, 5) Exit EndIf ; ;[IP and Port Settings] Local $sLocalIP = '127.0.0.1'; <- Any Valid Internal IP Local $nLocalPort = 8085; <- Any Valid Internal Port Local $sRemoteIP = '127.0.0.1'; <- Any Valid External IP Local $nRemotePort = 9085; <- Any Valid External Port ; Local $nListenSocket = _WSA_TCPListen($sLocalIP, $nLocalPort, 32) Local $nError = @error If $nError Then MsgBox(8208, $sTitle, 'Error: ' & $nError & ' _WSA_TCPListen' & @TAB, 5) Exit EndIf ; Local $nAcceptSocket, $nLocalSocket = 0, $nRemoteSocket = 1, $nActive = 0 Local $nBytesReceived, $nBytesSent, $sRecv, $nConnectSocket, $IDX = 32 Local $a[$IDX + 1][2] = [[$IDX, '']] ; While 1;[Main Loop] Do;[Idler Loop] $nAcceptSocket = _WSA_TCPAccept($nListenSocket); listen for an active socket. If $nAcceptSocket > 0 Then $nConnectSocket = _WSA_TCPConnect($sRemoteIP, $nRemotePort) If @error Then _WSA_TCPSend($nAcceptSocket, 'HTTP/1.1 444 No Response' & @CRLF & 'Connection: close' & @CRLF & @CRLF, 1); remote down? try again later. Sleep(250) _WSA_TCPCloseSocket($nAcceptSocket) Else For $i = 1 To $IDX If $a[$i][$nLocalSocket] < 1 Then $a[$i][$nLocalSocket] = $nAcceptSocket $a[$i][$nRemoteSocket] = $nConnectSocket $nActive = 1 ExitLoop EndIf Next EndIf EndIf Until $nActive ; ;[Active Loop] For $i = 1 To $IDX If $a[$i][$nLocalSocket] < 1 Then ContinueLoop EndIf ; ;[Client To Remote Loop] While $a[$i][$nLocalSocket] $sRecv = _WSA_TCPRecv($a[$i][$nLocalSocket], 32768, 1, 0); <- no timeout (keep-alive) $nError = @error $nBytesReceived = @extended ; If $nError Then _WSA_TCPCloseSocket($a[$i][$nLocalSocket]) _WSA_TCPCloseSocket($a[$i][$nRemoteSocket]) $a[$i][$nLocalSocket] = 0 ExitLoop ElseIf $nBytesReceived Then; client data received. $nActive = 1 $sRecv = BinaryToString($sRecv) _WSA_TCPSend($a[$i][$nRemoteSocket], $sRecv, 1); send client data to remote. $nError = @error $nBytesSent = @extended ; If $nError Then _WSA_TCPCloseSocket($a[$i][$nLocalSocket]) _WSA_TCPCloseSocket($a[$i][$nRemoteSocket]) $a[$i][$nLocalSocket] = 0 ExitLoop Else Sleep(10) ContinueLoop; check if more data exist. EndIf Else ExitLoop EndIf WEnd ; ;[Remote To Client Loop] While $a[$i][$nLocalSocket] $sRecv = _WSA_TCPRecv($a[$i][$nRemoteSocket], 32768, 1, 10); <- 10 second timeout if no activity. $nError = @error $nBytesReceived = @extended ; If $nError Then _WSA_TCPCloseSocket($a[$i][$nLocalSocket]) _WSA_TCPCloseSocket($a[$i][$nRemoteSocket]) $a[$i][$nLocalSocket] = 0 ExitLoop ElseIf $nBytesReceived Then; remote data received. $nActive = 1 $sRecv = BinaryToString($sRecv) _WSA_TCPSend($a[$i][$nLocalSocket], $sRecv, 1); send remote data to client. $nError = @error $nBytesSent = @extended ; If $nError Then _WSA_TCPCloseSocket($a[$i][$nLocalSocket]) _WSA_TCPCloseSocket($a[$i][$nRemoteSocket]) $a[$i][$nLocalSocket] = 0 ExitLoop Else Sleep(10) ContinueLoop; check if more data exist. EndIf Else ExitLoop EndIf WEnd Next ; ;[Proxy Reset] $nActive += 1 If $nActive > 500 Then For $i = 1 To $IDX If $a[$i][$nLocalSocket] > 0 Then _WSA_TCPSend($a[$i][$nLocalSocket], 'HTTP/1.1 504 Gateway Timeout' & @CRLF & 'Connection: close' & @CRLF & @CRLF, 1) Sleep(250) _WSA_TCPCloseSocket($a[$i][$nLocalSocket]) _WSA_TCPCloseSocket($a[$i][$nRemoteSocket]) EndIf $a[$i][$nLocalSocket] = 0 $a[$i][$nRemoteSocket] = 0 Next $nActive = 0 EndIf WEnd EndFunc ; Func ExitApp() _WSA_Cleanup() TCPShutdown() Exit EndFunc ;