udp穿透代理源代码(但有点小问题),希望高手帮忙解决(200分)

  • 主题发起人 主题发起人 gyp3085
  • 开始时间 开始时间
G

gyp3085

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdUDPBase, IdUDPClient, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient,Sockets,ScktComp,winsock,IdSocketHandle,IdStack,
IdUDPServer;

const
SOCKS_VER5=$05;

AUTH_NO=$00 ;//no authentication required
AUTH_REQU=$02 ;//method=0x02: username/password

CMD_CONNECT=$01 ;
CMD_UDP=$03 ;
RSV_DEFAULT=$00 ;
ATYP_DN=$03 ;
REP_SUCCESS=$00;
ATYP_IPV4=$01;


type
TProxyInfo = record // the Communication Block used in both parts (Server+Client)
Ip:string[15];
Port:integer;
end;

type
TForm1 = class(TForm)

IdUDPClient1: TIdUDPClient;
Label1: TLabel;
edtProxyAdd: TEdit;
Label2: TLabel;
edtproxyPort: TEdit;
CheckBox1: TCheckBox;
edtName: TEdit;
edtPassword: TEdit;
Label3: TLabel;
Label4: TLabel;
HostAddress: TEdit;
Port: TEdit;
Label5: TLabel;
Label6: TLabel;
MemoMessage: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
edtMessage: TEdit;
IdUDPServer1: TIdUDPServer;
LocalPort: TEdit;
Label7: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
private
{ Private declarations }
public
function GetIpAndPortFromProxy(skt: TTcpClient;target:TSockAddr): TProxyInfo;
function Auth(skt:TTcpClient; bauth: byte): boolean;
procedure SendData(strMessage,Ip:string;Port:integer;ProxyInfo:TProxyInfo);
end;

var
Form1: TForm1;
TcpClient:TTcpClient;
PubProxyInfo:TProxyInfo;
implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Re:integer;
tarsocksrv:TSockAddr;
AuthSucc:boolean;
ConSucc:boolean;
pSocksAddr:PChar;
ProxyInfo:TProxyInfo;
begin
IdUDPServer1.DefaultPort:=strtoint(LocalPort.Text);
IdUDPServer1.Active :=true;


TcpClient.Close ;
TcpClient.RemoteHost:=trim(edtProxyAdd.Text);
TcpClient.RemotePort:=trim(edtProxyPort.Text);
TcpClient.Open ;
MemoMessage.Lines.Add('连接代理服务器成功');

if CheckBox1.Checked then
AuthSucc:=Auth(TcpClient,AUTH_REQU)
else
AuthSucc:=Auth(TcpClient,AUTH_NO);

if not AuthSucc then
begin
MemoMessage.Lines.Add('验证失败');

TcpClient.Close ;

MemoMessage.Lines.Add('关闭socket');
Exit;
end;
MemoMessage.Lines.Add('验证成功');

ZeroMemory(@tarsocksrv,Sizeof(tarsocksrv));
//prepare
Getmem(psocksaddr,length('0.0.0.0')+1);
zeromemory(psocksaddr,length('0.0.0.0')+1);
strpcopy(psocksaddr,'0.0.0.0');
tarsocksrv.sin_addr.s_addr := inet_addr(pSocksAddr);
tarsocksrv.sin_port := htons(strtoint(LocalPort.text));
tarsocksrv.sin_family := AF_INET;
freemem(psocksaddr);

ProxyInfo:=GetIpAndPortFromProxy(TcpClient,tarsocksrv);

if ProxyInfo.Port<>-100 then
begin
MemoMessage.Lines.Add('从代理返回了ip和端口成功');
MemoMessage.Lines.Add('Ip:'+ProxyInfo.ip+'Port:'+inttostr(ProxyInfo.Port));
end
else
MemoMessage.Lines.add('从代理返回ip和端口失败');




end;

function Tform1.GetIpAndPortFromProxy(skt: TTcpClient;target:TSockAddr): TProxyInfo;
var
buf:array[0..1023]of byte;
re:integer;
sport,ProxyPort:word;
SIP:in_addr;
proxyIP:string;
tmpProxyInfo:TProxyInfo;
begin
//preapre
buf[0] := SOCKS_VER5;
buf[1] := CMD_UDP;
buf[2] := RSV_DEFAULT;
buf[3] := ATYP_IPV4;

//copy data
copymemory(@buf[4],@target.sin_addr,4);
copymemory(@buf[8],@target.sin_port,2);

//communicate

re:=skt.SendBuf(buf,10);

if re=-1 then
begin
tmpProxyInfo.Port :=-100;
result:=tmpProxyInfo;
exit;
end;

re:=skt.ReceiveBuf(buf,1024);
if re=-1 then
begin
tmpProxyInfo.Port :=-100;
result:=tmpProxyInfo;
exit;
end;
if buf[1]<>REP_SUCCESS then
begin
tmpProxyInfo.Port :=-100;
result:=tmpProxyInfo;
exit;
end;

//从代理返回的数据中得到ip和端口

copymemory(@sip,@buf[4],4);
tmpProxyInfo.ip:=inet_ntoa(sip);

CopyMemory(@sport, @Buf[8],2);
tmpProxyInfo.Port:=ntohs(sport);
PubProxyInfo:=tmpProxyInfo;
result:=tmpProxyInfo;
end;

procedure Tform1.SendData(strMessage,Ip:string;Port:integer;ProxyInfo:TProxyInfo);
var
buf:array of byte;
strLen:integer;
tarsocksrv:TSockAddr;
pSocksAddr:PChar;
begin

setlength(buf,length(strMessage)+10);

buf[0]:=0;
buf[1]:=0;
buf[2]:=0;
buf[3]:=1;
//目标主机地址
ZeroMemory(@tarsocksrv,Sizeof(tarsocksrv));
//prepare
strLen:=length(Ip)+1;
Getmem(psocksaddr,strLen);
zeromemory(psocksaddr,strLen);
strpcopy(psocksaddr,Ip);
tarsocksrv.sin_addr.s_addr := inet_addr(pSocksAddr);
tarsocksrv.sin_port := htons(Port);
tarsocksrv.sin_family := AF_INET;
freemem(psocksaddr);


copymemory(@buf[4],@tarsocksrv.sin_addr,4);
copymemory(@buf[8],@tarsocksrv.sin_port,2);


copymemory(@buf[10],@strMessage[1],length(strMessage));

IdUDPClient1.Host :=ProxyInfo.Ip;

IdUDPClient1.Port :=ProxyInfo.Port;
IdUDPClient1.Active :=true;

IdUDPClient1.SendBuffer(buf,length(strMessage)+10);
IdUDPClient1.Active :=false;

end;

function Tform1.Auth(skt:TTcpClient; bauth: byte): boolean;
var
buf:array[0..256]of byte;
re:integer;
i:integer;
usr:pchar;
pwd:pchar;
begin
getmem(usr, length(edtName.text)+1);
zeromemory(usr, length(edtName.text)+1);
strpcopy(usr,edtName.text);

getmem(pwd, length(edtPassword.text)+1);
zeromemory(pwd, length(edtPassword.text)+1);
strpcopy(pwd,edtPassword.text);
case bauth of
AUTH_NO:
begin
buf[0] := SOCKS_VER5;
buf[1] := $01;
buf[2] := $00;

re:=skt.SendBuf(buf,3);

if re=-1 then
begin
result:=false;
exit;
end;

re:=skt.ReceiveBuf(buf,257);
if re<2 then
begin
result:=false;
exit;
end;
if buf[1]<>AUTH_NO then
begin
result:=false;
exit;
end;
result:=true;
end;
AUTH_REQU:
begin
buf[0] := SOCKS_VER5;
buf[1] := $02;
buf[2] := $00;
buf[3] := $02;

re:=skt.SendBuf(buf,4);
if (re=-1)then
begin
result:=false;
exit;
end;
ZeroMemory(@buf,257);

re:=skt.ReceiveBuf(buf,257);
if (re < 2) then
begin
result:=false;
exit;
end;
if (buf[1] <> AUTH_REQU) then
begin
result:=false;
exit;
end;
zeromemory(@buf,257);

buf[0] := $01; //current version of subnegotiation
buf[1] := length(edtName.text); //length of username
for i:=0 to buf[1]-1 do
buf[2+i]:=ord(usr);
buf[2+length(edtName.text)]:=length(edtPassword.text);
for i:=0 to buf[2+length(edtName.text)]-1 do
buf[3+length(edtName.text)+i]:=ord(pwd);

re:=skt.SendBuf(buf,length(edtName.text)+length(edtPassword.text)+3);
if (re=-1) then
begin
result:=false;
exit;
end;

re:=skt.ReceiveBuf(buf,257);
if (buf[1] <> $00) then
begin
result:=FALSE;
exit;
end;
result:= TRUE;
end;

else
result:=false;
end;



freemem(usr);
freemem(pwd);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
TcpClient:=TTcpClient.Create(self);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
TcpClient.Close;
TcpClient.Free;

end;

procedure TForm1.Button3Click(Sender: TObject);
var
strMessage,ip:string;
Port:integer;
begin
strMessage:=trim(edtMessage.Text);
Ip:=Hostaddress.text;
Port:=strtoint(self.Port.Text) ;

SendData(strMessage,Ip,Port,PubProxyInfo);

{
IdUDPClient1.Host :=PubProxyInfo.Ip;

IdUDPClient1.Port :=PubProxyInfo.Port;

//IdUDPClient1.Host :='202.97.215.148';

//IdUDPClient1.Port :=23456;

IdUDPClient1.Active :=true;

IdUDPClient1.Send(strMessage);
IdUDPClient1.Active :=false;
}
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
DataStringStream: TStringStream;
begin
DataStringStream := TStringStream.Create('');
DataStringStream.CopyFrom(AData, AData.Size);
MemoMessage.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));

end;

end.
 
说说你遇到了什么问题??
 
后退
顶部