📄 redir_socks5.cpp.svn-base
字号:
#include "main.h"
#include "redir_socks5.h"
#include "mainctrl.h"
#include "utility.h"
#ifdef _WIN32
static CSocks5* socks;
u_long WINAPI SocksThread(LPVOID pParam);
bool CSocks::DNSAddrLookup(char* sHost, struct in_addr* addr)
{
struct hostent* ht = NULL;
ht = gethostbyname(sHost);
if(ht)
{
memcpy(addr,ht->h_addr, 4);
return(true);
}
return(false);
};
bool CSocks::SocksTCPTunneling(u_int sres, u_int sdest)
{
register u_int sockr, sockw, ret;
register u_int uread, uwrote;
char szBuffer[1024];
fd_set fd;
timeval tv = {0,0};
do
{
FD_ZERO(&fd);
FD_SET(sres,&fd);
FD_SET(sdest,&fd);
if((ret = select(2,&fd,NULL,NULL,&tv))>0 && VALID_SOCKET(ret))
{
if(FD_ISSET(sres,&fd))
{
sockr = sres;
sockw = sdest;
}
else
{
sockr = sdest;
sockw = sres;
}
uread = recv(sockr,szBuffer,1023,0);
szBuffer[uread] = 0;
uwrote = 0;
if(!VALID_SOCKET(uread) || uread==0) break;
while(uwrote<uread)
{
ret = send(sockw,szBuffer+uwrote,uread-uwrote,0);
if(!VALID_SOCKET(ret)) goto __quit;
uwrote += ret;
}
}
FD_ZERO(&fd);
FD_SET(sres,&fd);
FD_SET(sdest,&fd);
if(select(2,NULL,NULL,&fd,&tv)>0) break;
} while(1);
__quit:
return(true);
}
bool CSocks::SocksUDPTunneling(void* sares, char* sData, u_int len)
{
register u_int sdest, pos;
register u_int sres;
struct sockaddr_in sadest;
struct timeval tv;
struct fd_set fd;
char szBuffer[1024];
tv.tv_usec = 0;
tv.tv_sec = 7;
sadest.sin_family = AF_INET;
switch(sData[3])
{
case 1: memcpy(szBuffer,sData+4,4);
sadest.sin_addr.s_addr = *(u_long*)szBuffer;
sadest.sin_port = *(u_short*)(sData+8);
pos = 10;
break;
case 2: memcpy(szBuffer,sData+5,sData[4]);
szBuffer[sData[4]] = 0;
if(!DNSAddrLookup(szBuffer,&sadest.sin_addr)) return(false);
sadest.sin_port = *(u_short*)(sData+5+sData[4]);
pos = 7+sData[4];
break;
case 3: memcpy(szBuffer,sData+4,16);
szBuffer[16] = 0;
return(true);
default: return(false);
}
sdest = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
sres = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(!VALID_SOCKET(sdest) || VALID_SOCKET(sres)) return(false);
sendto(sdest,sData+pos,len-pos,0,(struct sockaddr*)&sadest,sizeof(sadest));
if(bind(sdest,(struct sockaddr*)sares,sizeof(struct sockaddr))) return(false);
do
{
FD_ZERO(&fd);
FD_SET(sres,&fd);
select(1,&fd,NULL,NULL,&tv);
pos = recvfrom(sdest,szBuffer,1023,0,NULL,NULL);
sendto(sres,szBuffer,pos,0,(struct sockaddr*)sares,sizeof(struct sockaddr));
} while(pos>0 && VALID_SOCKET(pos));
closesocket(sdest);
closesocket(sres);
return(true);
};
bool CSocks5::ForceConnection(u_int sock)
{
register u_int schain, ret, i;
char szBuffer[1024];
struct fd_set fd;
struct timeval tv;
struct sockaddr_in sain;
SOCKS5REQ req;
tv.tv_usec = 0;
tv.tv_sec = 11;
FD_ZERO(&fd);
FD_SET(sock,&fd);
if(!VALID_SOCKET(sock)) return(false);
if(mode==SOCKS_MODE_TCP)
{
if(select(1,&fd,NULL,NULL,&tv)>0 && FD_ISSET(sock,&fd))
{
schain = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if(!VALID_SOCKET(schain)) return(false);
recv(sock,szBuffer,2,0);
if(szBuffer[0]!=5) return(false);
ret = szBuffer[1];
memset(szBuffer,0,11);
recv(sock,szBuffer,ret,0);
char szLogin[256], szPassword[256];
send(sock,"\x05\x02",2,0);
tv.tv_usec = 0;
tv.tv_sec = 7;
FD_ZERO(&fd);
FD_SET(sock,&fd);
select(1,&fd,NULL,NULL,&tv);
memset(szBuffer,0,128);
recv(sock,szBuffer,2,0);
if(szBuffer[0]!=1) return(false);
recv(sock,szLogin,szBuffer[1],0);
szLogin[szBuffer[1]] = 0;
recv(sock,szBuffer,1,0);
recv(sock,szPassword,szBuffer[0],0);
szPassword[szBuffer[0]] = 0;
if(strcmp(szLogin,m_sUser.CStr()) && strcmp(szPassword,m_sPass.CStr()))
{
closesocket(sock);
return false;
}
send(sock,"\x05\x00",2,0);
FD_ZERO(&fd);
FD_SET(sock,&fd);
select(1,&fd,NULL,NULL,&tv);
if(!FD_ISSET(sock,&fd)) return(false);
recv(sock,(char*)&req,4,0);
switch(req.uAddrType) {
case 1: recv(sock,(char*)szBuffer,4,0); break;
case 3: recv(sock,(char*)szBuffer,1,0);
recv(sock,(char*)req.uDstAddr,szBuffer[0],0);
req.uDstAddr[szBuffer[0]] = 0;
if(!DNSAddrLookup((char*)req.uDstAddr,(struct in_addr*)szBuffer))
{
return(false);
}
break;
case 4: return(false);
default: ;
}
recv(sock,(char*)&req.uDstPort,sizeof(req.uDstPort),0);
if(req.uCommand==1)
{
sain.sin_family = AF_INET;
sain.sin_port = req.uDstPort;
sain.sin_addr.s_addr = *(u_long*)szBuffer;
if(connect(schain,(struct sockaddr*)&sain,sizeof(sain))!=0)
{
return(false);
}
}
else
{
return(false);
}
send(sock,"\x05\x00\x00\x01",4,0); // succeeded
send(sock,szBuffer,4,0);
send(sock,(char*)&req.uDstPort,2,0);
SocksTCPTunneling(sock,schain);
closesocket(schain);
}
}
else if(mode==SOCKS_MODE_UDP)
{
do
{
FD_ZERO(&fd);
FD_SET(sock,&fd);
select(1,&fd,NULL,NULL,&tv);
i = sizeof(sain);
ret = recvfrom(sock,szBuffer,1023,0,(struct sockaddr*)&sain,(int*)&i);
SocksUDPTunneling(&sain,szBuffer,ret);
} while(ret!=0 && VALID_SOCKET(ret) && FD_ISSET(sock,&fd));
}
return(true);
};
bool CSocks::PrepareListening()
{
register u_int uType, uProto;
struct sockaddr_in sain;
if(uAccept) return(false);
switch(mode)
{
case SOCKS_MODE_TCP:
uType = SOCK_STREAM; uProto = IPPROTO_TCP; break;
case SOCKS_MODE_UDP:
uType = SOCK_DGRAM; uProto = IPPROTO_UDP; break;
default:
mode = SOCKS_MODE_TCP;
uType = SOCK_STREAM; uProto = IPPROTO_TCP;
}
uAccept = socket(AF_INET,uType,uProto);
if(uAccept==0) return false;
sain.sin_family = AF_INET;
sain.sin_addr.s_addr = INADDR_ANY;
sain.sin_port = htons(uPort);
if(bind(uAccept,(struct sockaddr*)&sain,sizeof(sain))!=0)
{
closesocket(uAccept);
return false;
}
if(mode==SOCKS_MODE_TCP)
if(listen(uAccept,3)!=0)
{
closesocket(uAccept);
return false;
}
return(true);
};
bool CSocks::StartChaining()
{
register u_int sock, uTmp;
struct sockaddr_in sain;
bool bret;
if(mode==SOCKS_MODE_TCP)
{
uTmp = sizeof(sain);
if(uAccept==0) return(false);
while((sock = accept(uAccept,(struct sockaddr*)&sain,(int*)&uTmp))==0);
try {
bret = ForceConnection(sock);
closesocket(sock);
if(!bret) return false;
}
catch(...) {return false;}
}
else if(mode==SOCKS_MODE_UDP)
{
bret = ForceConnection(uAccept);
closesocket(uAccept);
if(!bret) return false;
}
else return false;
return(true);
}
u_long WINAPI SocksThread(LPVOID pParam)
{
CSocks5* pSocks = (CSocks5*)pParam;
try {
pSocks->ForceConnection(pSocks->uAccept);
closesocket(pSocks->uAccept);
}
catch(...) {
};
return(1);
}
void StartSocks5(int port, CString username, CString password)
{
WSAData wsadata;
if(WSAStartup(0x002,&wsadata)) return;
socks = new CSocks5();
socks->uPort=port;
socks->m_sUser=username;
socks->m_sPass=password;
if(!socks->PrepareListening()) return;
for(;;) socks->StartChaining();
return;
}
#endif // _WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -