Delphi-Cross-Socket icon indicating copy to clipboard operation
Delphi-Cross-Socket copied to clipboard

提交SocketV4 代理服务源码,欢迎补充SocketV5代码

Open xlnrony opened this issue 4 years ago • 0 comments

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.

xlnrony avatar Mar 19 '21 10:03 xlnrony