Delphi-Cross-Socket
Delphi-Cross-Socket copied to clipboard
提交SocketV4 代理服务源码,欢迎补充SocketV5代码
unit Net.CrossSocket4Server;
interface
uses Net.CrossSocket.Base, Net.CrossSocket, Net.CrossServer;
type TCrossSocket4Connection = class(TCrossConnection, ICrossConnection) private FCurrentStep: Integer; FOtherConnection: ICrossConnection; public constructor Create(AOwner: ICrossSocket; AClientSocket: THandle; AConnectType: TConnectType); override; end;
TCrossSocket4Server = class(TCrossServer) protected function CreateConnection(AOwner: ICrossSocket; AClientSocket: THandle; AConnectType: TConnectType): ICrossConnection; override; procedure LogicReceived(AConnection: ICrossConnection; ABuf: Pointer; ALen: Integer); override; end;
implementation
uses Winapi.Windows, System.SysUtils;
{$POINTERMATH ON} // +----+----+----+----+----+----+----+----+----+----+...+----+ // | VN | CD | DSTPORT | DSTIP | USERID |NULL| // +----+----+----+----+----+----+----+----+----+----+...+----+ // 1 1 2 4 variable 1 // // VN SOCKS协议版本号,应该是0x04 // CD SOCKS命令,可取如下值: // 0x01 CONNECT // 0x02 BIND // DSTPORT CD相关的端口信息 // DSTIP CD相关的地址信息 // USERID 客户方的USERID // NULL 0x00 // // 响应报文格式如下: // // +----+----+----+----+----+----+----+----+ // | VN | CD | DSTPORT | DSTIP | // +----+----+----+----+----+----+----+----+ // 1 1 2 4 // // VN 应该为0x00而不是0x04 // CD 可取如下值: // 0x5A 允许转发 // 0x5B 拒绝转发,一般性失败 // 0x5C 拒绝转发,SOCKS 4 Server无法连接到SOCS 4 Client所在主机的 // IDENT服务 // 0x5D 拒绝转发,请求报文中的USERID与IDENT服务返回值不相符 // DSTPORT CD相关的端口信息 // DSTIP CD相关的地址信息
const S4_VERSION = $04; S4_CONNECT = $01; S4_BIND = $02;
S4_CODE_5A = $5A; S4_CODE_5B = $5B; S4_CODE_5C = $5C; S4_CODE_5D = $5D;
{ TCrossSocket4Server }
function TCrossSocket4Server.CreateConnection(AOwner: ICrossSocket; AClientSocket: THandle; AConnectType: TConnectType): ICrossConnection; begin Result := TCrossSocket4Connection.Create(AOwner, AClientSocket, AConnectType); end;
procedure TCrossSocket4Server.LogicReceived(AConnection: ICrossConnection; ABuf: Pointer; ALen: Integer); var DstIP: array [0 .. 3] of Byte; DstPort: array [0 .. 1] of Byte; DstIPString: string; DstPortWord: Word; begin try with AConnection as TCrossSocket4Connection do begin case FCurrentStep of 1: begin if (PByte(ABuf)[0] <> S4_VERSION) or (PByte(ABuf)[1] = S4_BIND) then begin AConnection.Disconnect; Exit; end;
if PByte(ABuf)[1] = S4_CONNECT then
begin
Move((PByte(ABuf) + 4)^, DstIP, 4);
Move((PByte(ABuf) + 2)^, DstPort, 2);
DstIPString := Format('%d.%d.%d.%d',
[DstIP[0], DstIP[1], DstIP[2], DstIP[3]]);
DstPortWord := (DstPort[0] shl 8) + DstPort[1];
OutputDebugString(PChar('SockV4: Relay To ' + DstIPString + ':' +
IntToStr(DstPortWord)));
Connect(DstIPString, DstPortWord,
procedure(Connection: ICrossConnection; Success: Boolean)
var
Buf8: array [0 .. 7] of Byte;
begin
FillChar(Buf8, 8, 0);
if Success then
begin
(Connection as TCrossSocket4Connection).FOtherConnection :=
AConnection;
FOtherConnection := Connection;
(Connection as TCrossSocket4Connection).FCurrentStep := 2;
FCurrentStep := 2;
Buf8[1] := S4_CODE_5A;
end
else
begin
Buf8[1] := S4_CODE_5B;
end;
AConnection.SendBuf(@Buf8, 8);
end);
end;
end;
2:
begin
FOtherConnection.SendBuf(ABuf, ALen);
end;
end;
end;
except on E: Exception do begin OutputDebugString(PChar('SockV4:' + E.Message)); AConnection.Disconnect; end; end; end;
{ TCrossSocket4Connection }
constructor TCrossSocket4Connection.Create(AOwner: ICrossSocket; AClientSocket: THandle; AConnectType: TConnectType); begin inherited; FCurrentStep := 1; end;
end.