真正socks5代理源码 VC

http://blog.macrowen.com/Technology/64.html

// Author: LZX
// E-mail: LZX@qq.com
// Version: V1.0 (Multithreads Mode)
// Purpose: A Proxy works on one port and supports SOCKS v4 && v5 && Http protocol.
//          The socks proxy request has not supported BIND method yet.
//          The Http proxy supports three methods:GET(HEAD) POST CONNECT.
// Test PlatForm: WinXP SP2
// Compiled On: VC++ 6.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <errno.h>
#pragma comment(lib,"ws2_32.lib")
#define MAX_HOSTNAME 256
#define DEFAULTPORT   80
#define LISTENPORT   1080
#define DEFLISNUM   50
#define MAXBUFSIZE   20480
#define TIMEOUT    10000
#define HEADLEN    7
char ErrorMsg[]="Http/1.1 403 Forbidden\r\n\r\n<body><h1>403 Forbidden</h1></body>";
char ConnectionEstablished[]="HTTP/1.0 200 OK\r\n\r\n";
int LisPort;
char Username[256]="\0";
char Password[256]="\0";
struct Socks4Req
{
    BYTE Ver;
    BYTE REP;
    WORD wPort;
    DWORD dwIP;
    BYTE other[1];
};
struct Socks5Req
{
    BYTE Ver;
    BYTE nMethods;
    BYTE Methods[255];
};
struct AuthReq
{
    BYTE Ver;
    BYTE Ulen;
    BYTE UserPass[1024];
};
typedef struct
{
BYTE Ver;      // Version Number
BYTE CMD;      // 0x01==TCP CONNECT,0x02==TCP BIND,0x03==UDP ASSOCIATE
BYTE RSV;
BYTE ATYP;
BYTE IP_LEN;
BYTE szIP;
}Socks5Info;
typedef struct
{
DWORD dwIP;
WORD wPort;
}IPandPort;
typedef struct
{
BYTE Ver;
BYTE REP;
BYTE RSV;
BYTE ATYP;
IPandPort IPandPort;
}Socks5AnsConn;
typedef struct
{
BYTE RSV[2];
BYTE FRAG;
BYTE ATYP;
IPandPort IPandPort;
// BYTE DATA;
}Socks5UDPHead;
struct SocketInfo
{
SOCKET socks;
IPandPort IPandPort;
};
typedef struct
{
SocketInfo Local;
SocketInfo Client;
SocketInfo Server;
}Socks5Para;
// End Of Structure
static CRITICAL_SECTION cs;
void TCPTransfer(SOCKET* CSsocket);
void UDPTransfer(Socks5Para *sPara);
BOOL ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const WORD RemotePort);
/
//---------------------------------------------------------------------------
void GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,UINT *RemotePort)
{
char *fp = ReceiveBuf;
for(int i = 0;i < datalen && *fp != ':' && *fp != '\0' && *fp != '\r' && *fp != '/';i++)
{
   HostName[i]=*fp++;
   if(*fp == ':')
    *RemotePort=atoi(fp+1);
   else *RemotePort=DEFAULTPORT;
}
}
//---------------------------------------------------------------------------
char * GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen)
{
for(int i = 0;i < DataLen; i++)
{
   if(ReceiveBuf[i] == '/')
   {
    *HostNaneLen = i;
    return &ReceiveBuf[i];
   }
}
return NULL;
}
//---------------------------------------------------------------------------
int CheckRequest(char *ReceiveBuf,int *MethodLength)
{
if(!strnicmp(ReceiveBuf,"GET ",4))
{
   *MethodLength = 4;
   return 1;
}
else if(!strnicmp(ReceiveBuf,"HEAD ",5)) //Looks like the same with GET
{
   *MethodLength = 5;
   return 2;
}
else if(!strnicmp(ReceiveBuf,"POST ",5))
{
   *MethodLength = 5;
   return 3;
}
else if(!strnicmp(ReceiveBuf,"CONNECT ",8))
{
   *MethodLength = 8;
   return 4;
}
else
{
   return 0;
}
}
int ModifyRequest(char *SenderBuf,char *ReceiveBuf,int DataLen,int MethodLength)
{
strncpy(SenderBuf,ReceiveBuf,MethodLength);
int HedLen = 0;
if(strncmp(ReceiveBuf+MethodLength,"http://",HEADLEN))
   return 0;
char * Getrootfp = GetURLRootPoint(ReceiveBuf+MethodLength+HEADLEN,DataLen-MethodLength-HEADLEN,&HedLen);
if(Getrootfp == NULL)
   return 0;
memcpy(SenderBuf+MethodLength,Getrootfp,DataLen-MethodLength-HEADLEN-HedLen);
return DataLen-HEADLEN-HedLen;
}
BOOL SendRequest(SOCKET* CSsocket, char *SenderBuf, char *ReceiveBuf, int DataLen)
{
//CSsocket[0] ClientSocket
//CSsocket[1] ServerSocket
DWORD dwThreadID;
char   HostName[MAX_HOSTNAME] = {0};
char   ReqInfo1[8],ReqInfo2[248];
UINT   RemotePort = 0;
static t=0;
EnterCriticalSection(&cs);
int n=++t;
LeaveCriticalSection(&cs);
int Flag=0, MethodLength=0, SendLength=0;
Flag = CheckRequest(ReceiveBuf,&MethodLength);
if(Flag==0) return 0;
if(Flag==1 || Flag==2 || Flag==3)
{
   SendLength=ModifyRequest(SenderBuf,ReceiveBuf,DataLen,MethodLength);
   if(!SendLength)
    return 0;
   GetHostNameAndPort(ReceiveBuf+MethodLength+HEADLEN,DataLen-MethodLength-HEADLEN,HostName,&RemotePort);
   if(!ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort))
    return 0;
   if(send(CSsocket[1],SenderBuf,SendLength,0) == SOCKET_ERROR)
    return 0;
}else if(Flag==4)
{
   GetHostNameAndPort(ReceiveBuf+MethodLength,DataLen-MethodLength,HostName,&RemotePort);
   if(!ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort))
    return 0;
   send(CSsocket[0], ConnectionEstablished, strlen(ConnectionEstablished)+1,0);
}
if(CSsocket[0] && CSsocket[1])
{
   //printf("HTTP Proxy request %d OK.\n",n);
   //sscanf(ReceiveBuf,"%s %s",ReqInfo1,ReqInfo2);
   //printf("%s %s\n",ReqInfo1,ReqInfo2);
   HANDLE ThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPTransfer,(LPVOID)CSsocket,0,&dwThreadID);
   if (ThreadHandle != NULL)
   {
    WaitForSingleObject(ThreadHandle, INFINITE);
    //printf("HTTP Proxy request %d Exit.\n",n);
   }
}else
   return 0;
return 1;
}
/
int Authentication(SOCKET* CSsocket, char *ReceiveBuf,int DataLen)
{
Socks5Req *sq;
char Method[2]={0x05,0};
sq=(Socks5Req *)ReceiveBuf;
printf("%d,%d,%d,%d,%d\n",sq->Ver,sq->nMethods,sq->Methods[0],sq->Methods[1],sq->Methods[2]);
if(sq->Ver!=5)
   return sq->Ver;
if((sq->Methods[0]==0)||(sq->Methods[0]==2))//00,无需认证;01,GSSAPI;02,需要用户名和PASSWORD
{
   if(strlen(Username)==0)
    Method[1]=0x00;
   else
    Method[1]=0x02;
   if(send(CSsocket[0],Method,2,0) == SOCKET_ERROR)
    return 0;
}else
   return 0;
if(Method[1]==0x02)//00,无需认证;01,GSSAPI;02,需要用户名和PASSWORD
{
   char USER[256];
   char PASS[256];
   memset(USER,0,sizeof(USER));
   memset(PASS,0,sizeof(PASS));
   DataLen = recv(CSsocket[0],ReceiveBuf,MAXBUFSIZE,0);
   if(DataLen == SOCKET_ERROR || DataLen == 0)
    return 0;
   AuthReq *aq=(AuthReq *)ReceiveBuf;
   if(aq->Ver!=1)
    return 0;
   if((aq->Ulen!=0)&&(aq->Ulen<=256))
    memcpy(USER,ReceiveBuf+2,aq->Ulen);
   int PLen=ReceiveBuf[2+aq->Ulen];
   if((PLen!=0)&&(PLen<=256))
    memcpy(PASS,ReceiveBuf+3+aq->Ulen,PLen);
   //printf("USER %s\nPASS %s\n",USER,PASS);
   //0=login successfully,0xFF=failure;
   if(!strcmp(Username,USER) && !strcmp(Password,PASS))
   {
    ReceiveBuf[1]=0x00;
    //printf("Socks5 Authentication Passed\n");
   }
   else
   {
    ReceiveBuf[1]=0xFF;
    //printf("Invalid Password\n");
   }
   if(send(CSsocket[0],ReceiveBuf,2,0) == SOCKET_ERROR)
    return 0;
}
return 1;
}
char *GetInetIP(char *OutIP)
{
// Get host adresses
char addr[16];
struct hostent * pHost;
pHost = gethostbyname("");
for( int i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
{
   OutIP[0]=0;
   for( int j = 0; j < pHost->h_length; j++ )
   {
    if( j > 0 ) strcat(OutIP,".");
    sprintf(addr,"%u", (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]);
    strcat(OutIP,addr);
   }
}
return OutIP;
}
char *DNS(char *HostName)
{
HOSTENT *hostent = NULL;
IN_ADDR iaddr;
hostent = gethostbyname(HostName);
if (hostent == NULL)
{
   return NULL;
}
iaddr = *((LPIN_ADDR)*hostent->h_addr_list);
return inet_ntoa(iaddr);
}
int GetAddressAndPort(char *ReceiveBuf, int DataLen, int ATYP, char *HostName, WORD *RemotePort)
{
DWORD Socks5InfoSize = sizeof(Socks5Info);
DWORD dwIndex = 0;
Socks4Req *Socks4Request=(Socks4Req *)ReceiveBuf;
Socks5Info *Socks5Request=(Socks5Info *)ReceiveBuf;
struct sockaddr_in in;
if(ATYP==2) //Socks v4 !!!
{
   *RemotePort=ntohs(Socks4Request->wPort);
   if(ReceiveBuf[4]!=0x00) //USERID !!
    in.sin_addr.s_addr = Socks4Request->dwIP;
   else
    in.sin_addr.s_addr = inet_addr(DNS((char*)&Socks4Request->other+1));
   memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));
   return 1;
}
//ATYP=0x01代表IP V4地址 0x03代表域名;
if((Socks5Request->Ver==5)&&(ATYP==1))
{
   IPandPort *IPP=(IPandPort *)&Socks5Request->IP_LEN;
   in.sin_addr.S_un.S_addr = IPP->dwIP;
   memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));
   *RemotePort = ntohs(IPP->wPort);
}
else if((Socks5Request->Ver==5)&&(ATYP==3))
{
   memcpy(HostName, &Socks5Request->szIP, Socks5Request->IP_LEN);
   memcpy(RemotePort, &Socks5Request->szIP+Socks5Request->IP_LEN, 2);
   *RemotePort=ntohs(*RemotePort);
}else if((Socks5Request->Ver==0)&&(Socks5Request->CMD==0)&&(ATYP==1))
{
   IPandPort *IPP=(IPandPort *)&Socks5Request->IP_LEN;
   in.sin_addr.S_un.S_addr = IPP->dwIP;
   memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));
   *RemotePort = ntohs(IPP->wPort);
   return 10; //return Data Enter point
}else if((Socks5Request->Ver==0)&&(Socks5Request->CMD==0)&&(ATYP==3))
{
   memcpy(HostName, &Socks5Request->szIP, Socks5Request->IP_LEN);
   memcpy(RemotePort, &Socks5Request->szIP+Socks5Request->IP_LEN, 2);
   *RemotePort=ntohs(*RemotePort);
   return 7+Socks5Request->IP_LEN; //return Data Enter point
}else
   return 0;
return 1;
}
BOOL ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const WORD RemotePort)
{
struct sockaddr_in Server;
memset(&Server, 0, sizeof(Server));
Server.sin_family = AF_INET;
Server.sin_port = htons(RemotePort);
if (inet_addr(HostName) != INADDR_NONE)
   Server.sin_addr.s_addr = inet_addr(HostName);
else
{
   if (DNS(HostName) != NULL)
    Server.sin_addr.s_addr = inet_addr(DNS(HostName));
   else
    return FALSE;
}
// Create Socket
*ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (*ServerSocket == INVALID_SOCKET)
   return FALSE;
UINT TimeOut = TIMEOUT;
setsockopt(*ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut));
if (connect(*ServerSocket, (const SOCKADDR *)&Server,sizeof(Server)) == SOCKET_ERROR)
{
   printf("Fail To Connect To Remote Host\n");
   closesocket(*ServerSocket);
   return FALSE;
}
return TRUE;
}
int TalkWithClient(SOCKET *CSsocket, char *ReceiveBuf, int DataLen, char *HostName, WORD *RemotePort)
{
//CSsocket[0] ClientSocket
//CSsocket[1] ServerSocket
int Flag=0;
//Username Password Authentication
Flag = Authentication(CSsocket, ReceiveBuf, DataLen);
if(Flag==0) return 0;
if(Flag==4) //Processing Socks v4 requests......
{//The third parameter ATYP==2 is not used for Socks5 protocol,I use it to flag the socks4 request.
   if(!GetAddressAndPort(ReceiveBuf, DataLen, 2, HostName, RemotePort))
    return 0;
   return 4;
}
//Processing Socks v5 requests......
DataLen = recv(CSsocket[0],ReceiveBuf,MAXBUFSIZE,0);
if(DataLen == SOCKET_ERROR || DataLen == 0)
   return 0;
Socks5Info *Socks5Request=(Socks5Info *)ReceiveBuf;
if (Socks5Request->Ver != 5) //Invalid Socks 5 Request
{
   //printf("Invalid Socks 5 Request\n");
   return 0;
}
//Get IP Type //0x01==IP V4地址 0x03代表域名;0x04代表IP V6地址;not Support
if((Socks5Request->ATYP==1)||(Socks5Request->ATYP==3))
{
   if(!GetAddressAndPort(ReceiveBuf, DataLen, Socks5Request->ATYP, HostName, RemotePort))
    return 0;
}else return 0;
//Get and return the work mode. 1:TCP CONNECT   3:UDP ASSOCIATE
if((Socks5Request->CMD == 1)||(Socks5Request->CMD == 3))
   return Socks5Request->CMD;
return 0;
}
BOOL CreateUDPSocket(Socks5AnsConn *SAC, SOCKET *socks)
{
char szIP[256];
struct sockaddr_in UDPServer;
struct sockaddr_in in;
memset(&in,0,sizeof(sockaddr_in));
int structsize=sizeof(sockaddr_in);
UDPServer.sin_family=AF_INET;
UDPServer.sin_addr.s_addr= INADDR_ANY;
UDPServer.sin_port=INADDR_ANY;
SOCKET Locals = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(Locals == SOCKET_ERROR)
{
   //printf("UDP socket create failed.\n");
   return 0;
}
if(bind(Locals,(SOCKADDR*)&UDPServer, sizeof(UDPServer)) == SOCKET_ERROR)
{
   //printf("UDP socket bind failed.\n");
   return 0;
}
UINT TimeOut = TIMEOUT;
//setsockopt(Locals,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut));
*socks = Locals;
getsockname(Locals,(struct sockaddr *)&in,&structsize);
SAC->IPandPort.dwIP = inet_addr(GetInetIP(szIP));
SAC->IPandPort.wPort = in.sin_port;
//printf("UDP Bound to %s:%d\r\n", szIP, ntohs(in.sin_port));
return 1;
}
DWORD WINAPI ZXProxyThread(SOCKET* CSsocket)
{
DWORD dwThreadID;
static t=0;
EnterCriticalSection(&cs);
int n=++t;
LeaveCriticalSection(&cs);
WORD   RemotePort = 0;
char *HostName = (char*)malloc(sizeof(char)*MAX_HOSTNAME);
char *ReceiveBuf = (char*)malloc(sizeof(char)*MAXBUFSIZE);
char *SenderBuf = (char*)malloc(sizeof(char)*MAXBUFSIZE);
Socks4Req Socks4Request;
Socks5AnsConn SAC;
memset(HostName,0,MAX_HOSTNAME);
memset(ReceiveBuf,0,MAXBUFSIZE);
memset( SenderBuf,0,MAXBUFSIZE);
memset(&SAC,0,sizeof(SAC));
/UDP variable
Socks5Para sPara;
struct sockaddr_in in;
memset(&sPara,0,sizeof(Socks5Para));
memset(&in,0,sizeof(sockaddr_in));
int structsize=sizeof(sockaddr_in);

int DataLen = 0,Flag = 0,ProtocolVer=0;
DataLen = recv(CSsocket[0],ReceiveBuf,MAXBUFSIZE,0);
if(DataLen == SOCKET_ERROR || DataLen == 0)
   goto exit;
if(SendRequest(CSsocket, SenderBuf, ReceiveBuf, DataLen)) //http proxy
   goto exit;
Flag=TalkWithClient(CSsocket, ReceiveBuf, DataLen, HostName, &RemotePort);
if(!Flag)
{
   /*SAC.Ver=0x05;
   SAC.REP=0x01;
   SAC.ATYP=0x01;
   send(CSsocket[0], (char *)&SAC, 10, 0);*/
   goto exit;
}
else if(Flag==1) //TCP CONNECT
{
   ProtocolVer=5;
   if(!ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort))
    SAC.REP=0x01;
   SAC.Ver=0x05;
   SAC.ATYP=0x01;
   if(send(CSsocket[0], (char *)&SAC, 10, 0) == SOCKET_ERROR)
    goto exit;
   if(SAC.REP==0x01) // general SOCKS server failure
    goto exit;
}
else if(Flag==3) //UDP ASSOCIATE
{ //ProcessingUDPsession;
   ProtocolVer=5;
   //Save the client connection information(client IP and source port)
   getpeername(CSsocket[0],(struct sockaddr *)&in,&structsize);
   if(inet_addr(HostName)==0)
    sPara.Client.IPandPort.dwIP = in.sin_addr.s_addr;
   else
    sPara.Client.IPandPort.dwIP = inet_addr(DNS(HostName));
   printf("Accept ip:%s\n",inet_ntoa(in.sin_addr));
   sPara.Client.IPandPort.wPort= htons(RemotePort);/
   sPara.Client.socks=CSsocket[0];
   if(!CreateUDPSocket(&SAC,&sPara.Local.socks)) //Create a local UDP socket
    SAC.REP=0x01;
   SAC.Ver=5;
   SAC.ATYP=1;
   if(send(CSsocket[0], (char *)&SAC, 10, 0) == SOCKET_ERROR)
    goto exit;
   if(SAC.REP==0x01) // general SOCKS server failure
    goto exit;
   sPara.Local.IPandPort=SAC.IPandPort; //Copy local UDPsocket data structure to sPara.Local
   // Create UDP Transfer thread
   HANDLE ThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)UDPTransfer,(LPVOID)&sPara,0,&dwThreadID);
   if (ThreadHandle != NULL)
   {
    //printf("Socks%d UDP Session-> %s:%d\n",ProtocolVer,inet_ntoa(in.sin_addr),ntohs(sPara.Client.IPandPort.wPort));
    WaitForSingleObject(ThreadHandle, INFINITE);
    //printf("UDPTransfer Thread %d Exit.\n",n);
   }else
    goto exit;
   return 1;
   
}
else if(Flag==4) // Socks v4! I use the return value==4 to flag the Socks v4 request.
{
   ProtocolVer=4;
   memset(&Socks4Request, 0, 9);
   if(!ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort))
    Socks4Request.REP = 0x5B; //REJECT
   else
    Socks4Request.REP = 0x5A; //GRANT
   if(send(CSsocket[0], (char *)&Socks4Request, 8, 0) == SOCKET_ERROR)
    goto exit;
   if(Socks4Request.REP==0x5B)   //ConnectToRemoteHost failed,closesocket and free some point.
    goto exit;
}else
   goto exit;
if(CSsocket[0] && CSsocket[1])
{
   //printf("Socks%d TCP Session-> %s:%d\n",ProtocolVer,HostName,RemotePort);
   HANDLE ThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPTransfer,(LPVOID)CSsocket,0,&dwThreadID);
   if (ThreadHandle != NULL)
   {
    WaitForSingleObject(ThreadHandle, INFINITE);
   }
}else
   goto exit;
goto exit;
exit:
closesocket(CSsocket[0]);
closesocket(CSsocket[1]);
free(CSsocket);
free(HostName);
free(SenderBuf);
free(ReceiveBuf);
return 0;
}
BOOL StartProxy()
{
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData))
   return false;
SOCKET ProxyServer= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ProxyServer == SOCKET_ERROR)
   return false;
struct sockaddr_in Server={0};
Server.sin_family = AF_INET;
Server.sin_port = htons(LisPort);
Server.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(ProxyServer, (LPSOCKADDR)&Server, sizeof(Server)) == SOCKET_ERROR)
   return false;
if(listen(ProxyServer, DEFLISNUM) == SOCKET_ERROR)
   return false;
SOCKET AcceptSocket = INVALID_SOCKET;
SOCKET *CSsocket;
DWORD dwThreadID;
printf("Now listening on port: %d\r\n",LisPort);
while(1)
{
   AcceptSocket = accept(ProxyServer, NULL, NULL);
   //printf("Accepting New Requests\n");
   CSsocket = (SOCKET*)malloc(sizeof(SOCKET)*2);
   if (CSsocket == NULL)
   {
    //printf("Fail To Allocate Ram\n");
    continue;
   }
   CSsocket[0] = AcceptSocket;
   HANDLE hThread = CreateThread (NULL,0, (LPTHREAD_START_ROUTINE)ZXProxyThread,CSsocket,0, &dwThreadID);        // Create Thread To Handle Request
   if (hThread == NULL)        // Fail To Create Socket
   {
    //printf("Fail To Create Thread.Probably Too Many Threads Have Been Created\n");
    Sleep(1000);
   }
   else
   {
    CloseHandle(hThread);
   }
}
}
void main(int argc, char* argv[])
{
LisPort=LISTENPORT;
if(argc>1)
   LisPort=atoi(argv[1]);
if(argc==4)
{
   strcpy(Username,argv[2]);
   strcpy(Password,argv[3]);
}
printf("SOCKS v4 && v5 && Http Proxy V1.0 By LZX.\r\nUsage:\n%s ProxyPort (Default port 1080)\n%s ProxyPort Username Password\n",argv[0],argv[0]);
InitializeCriticalSection(&cs);
StartProxy();
WSACleanup();
DeleteCriticalSection(&cs);
}

int UDPSend(SOCKET s, char *buff, int nBufSize, struct sockaddr_in *to,int tolen)
{
int nBytesLeft = nBufSize;
int idx = 0, nBytes = 0;
while(nBytesLeft > 0)
{
   nBytes = sendto(s, &buff[idx], nBytesLeft, 0, (SOCKADDR *)to, tolen);
   if(nBytes == SOCKET_ERROR)
   {
    //printf("Failed to send buffer to socket %d.\r\n", WSAGetLastError());
    return SOCKET_ERROR;
   }
   nBytesLeft -= nBytes;
   idx += nBytes;
}
return idx;
}
void UDPTransfer(Socks5Para *sPara)!!!!!!!!!!!!!!!!
{
struct sockaddr_in SenderAddr;
int   SenderAddrSize=sizeof(SenderAddr),DataLength=0,result;
char RecvBuf[MAXBUFSIZE];
struct sockaddr_in UDPClient,UDPServer;
memset(&UDPClient,0,sizeof(sockaddr_in));
memset(&UDPServer,0,sizeof(sockaddr_in));
UDPClient.sin_family = AF_INET;
UDPClient.sin_addr.s_addr = sPara->Client.IPandPort.dwIP;
UDPClient.sin_port = sPara->Client.IPandPort.wPort;
/*/test
Socks5UDPHead test;
memset(&test,0,sizeof(Socks5UDPHead));
test.RSV[0]=0x05;
test.ATYP=0x01;
test.IPandPort=sPara->Local.IPandPort;
if(sendto(sPara->Local.socks,(char*)&test, 10,0,(struct sockaddr FAR *)&UDPClient,sizeof(UDPClient)) == SOCKET_ERROR)
{
   //printf("test sendto server error.\n");
   return;
}*/
//printf("UDPTransfer thread start......\n");
fd_set readfd;
while(1)
{
   FD_ZERO(&readfd);
   FD_SET((UINT)sPara->Local.socks, &readfd);
   FD_SET((UINT)sPara->Client.socks, &readfd);
   result=select(sPara->Local.socks+1,&readfd,NULL,NULL,NULL);
   if((result<0) && (errno!=EINTR))
   {
    //printf("Select error.\r\n");
    break;
   }
   if(FD_ISSET(sPara->Client.socks, &readfd))
    break;
   if(FD_ISSET(sPara->Local.socks, &readfd))
   {
   memset(RecvBuf,0,MAXBUFSIZE);
   DataLength=recvfrom(sPara->Local.socks,
    RecvBuf+10, MAXBUFSIZE-10, 0, (struct sockaddr FAR *)&SenderAddr, &SenderAddrSize);
   if(DataLength==SOCKET_ERROR)
   {
    //printf("UDPTransfer recvfrom error.\n");
    break;
   }//SenderAddr.sin_addr.s_addr==sPara->Client.IPandPort.dwIP&&
   if(SenderAddr.sin_port==sPara->Client.IPandPort.wPort)//Data come from client
   {
    //这里要先修改udp数据报头
    WORD RemotePort = 0;
    char HostName[MAX_HOSTNAME];
    memset(HostName,0,MAX_HOSTNAME);
    int DataPoint=GetAddressAndPort(RecvBuf+10, DataLength, RecvBuf[13], HostName, &RemotePort);
    if(DataPoint)
    {
     printf("Data come from client IP: %s:%d | %d Bytes.\n",
     // inet_ntoa(SenderAddr.sin_addr),ntohs(SenderAddr.sin_port),DataLength);
     //send data to server
     printf("IP: %s:%d || DataPoint: %d\n",HostName,RemotePort,DataPoint);
     UDPServer.sin_family=AF_INET;
     UDPServer.sin_addr.s_addr= inet_addr(DNS(HostName));
     UDPServer.sin_port=htons(RemotePort);
     result=UDPSend(sPara->Local.socks,RecvBuf+10+DataPoint, DataLength-DataPoint,&UDPServer,sizeof(UDPServer));
     if(result == SOCKET_ERROR)
     {
      //printf("sendto server error\n");
      break;
     }
     printf("Data(%d) sent to server succeed.|| Bytes: %d\n",DataLength-DataPoint,result);
    }else break;
   }else if(SenderAddr.sin_port==UDPServer.sin_port)//Data come from server
   {//SenderAddr.sin_addr.s_addr==UDPServer.sin_addr.s_addr&&
    //send data to client
    printf("Data come from server IP: %s:%d | %d Bytes.\n",
    // inet_ntoa(SenderAddr.sin_addr),ntohs(SenderAddr.sin_port),DataLength);
    Socks5UDPHead *UDPHead = (Socks5UDPHead*)RecvBuf;
    memset(UDPHead,0,10);
    UDPHead->ATYP=0x01;
    UDPHead->IPandPort=sPara->Client.IPandPort;
    //UDPHead->IPandPort.dwIP =SenderAddr.sin_addr.s_addr;
    //UDPHead->IPandPort.wPort=SenderAddr.sin_port;
    //memcpy(&UDPHead->DATA-2,RecvBuf,DataLength);//UDPHead->DATA-2!!!!!!!!!!!!
    result=UDPSend(sPara->Local.socks,RecvBuf,DataLength+10,&UDPClient,sizeof(UDPClient));
    if(result == SOCKET_ERROR)
    {
     printf("sendto client error\n");
     break;
    }
    //printf("Data(%d) sent to client succeed.|| Bytes: %d\n",DataLength+10,result);
   }else
   {
    //printf("!!!!!The data are not from client or server.drop it.%s\n",inet_ntoa(SenderAddr.sin_addr));
   }
   }
   Sleep(5);
}
closesocket(sPara->Local.socks);
closesocket(sPara->Client.socks);
}
void TCPTransfer(SOCKET* CSsocket)
{
SOCKET ClientSocket = CSsocket[0];
SOCKET ServerSocket = CSsocket[1];
struct timeval timeset;
fd_set readfd,writefd;
int result,i=0;
char read_in1[MAXBUFSIZE],send_out1[MAXBUFSIZE],SenderBuf[MAXBUFSIZE];
char read_in2[MAXBUFSIZE],send_out2[MAXBUFSIZE];
int read1=0,totalread1=0,send1=0;
int read2=0,totalread2=0,send2=0;
int sendcount1,sendcount2;
int maxfd;
maxfd=max(ClientSocket,ServerSocket)+1;
memset(read_in1,0,MAXBUFSIZE);
memset(read_in2,0,MAXBUFSIZE);
memset(send_out1,0,MAXBUFSIZE);
memset(send_out2,0,MAXBUFSIZE);
timeset.tv_sec=TIMEOUT;
timeset.tv_usec=0;
while(1)
{
   FD_ZERO(&readfd);
   FD_ZERO(&writefd);
   FD_SET((UINT)ClientSocket, &readfd);
   FD_SET((UINT)ClientSocket, &writefd);
   FD_SET((UINT)ServerSocket, &writefd);
   FD_SET((UINT)ServerSocket, &readfd);
   result=select(maxfd,&readfd,&writefd,NULL,&timeset);
   if((result<0) && (errno!=EINTR))
   {
    printf("Select error.\r\n");
    break;
   }
   else if(result==0)
   {
    printf("Socket time out.\r\n");
    break;
   }
   if(FD_ISSET(ServerSocket, &readfd))
   {
    if(totalread2<MAXBUFSIZE)
    {
     read2=recv(ServerSocket,read_in2,MAXBUFSIZE-totalread2, 0);
     if(read2==0)break;
     if((read2<0) && (errno!=EINTR))
     {
      printf("Read ServerSocket data error,maybe close?\r\n\r\n");
      break;
     }
     memcpy(send_out2+totalread2,read_in2,read2);
             totalread2+=read2;
             memset(read_in2,0,MAXBUFSIZE);
    }
        }
   if(FD_ISSET(ClientSocket, &writefd))
     {
    int err2=0;
         sendcount2=0;
         while(totalread2>0)
         {
         send2=send(ClientSocket, send_out2+sendcount2, totalread2, 0);
            if(send2==0)break;
            if((send2<0) && (errno!=EINTR))
            {
             printf("Send to ClientSocket unknow error.\r\n");
      err2=1;
             break;
            }
            if((send2<0) && (errno==ENOSPC)) break;
            sendcount2+=send2;
            totalread2-=send2;
         }
    if(err2==1) break;
        if((totalread2>0) && (sendcount2 > 0))
    {
     /* move not sended data to start addr */
     memcpy(send_out2, send_out2+sendcount2, totalread2);
     memset(send_out2+totalread2, 0, MAXBUFSIZE-totalread2);
    }
    else
     memset(send_out2,0,MAXBUFSIZE);
   }
   if(FD_ISSET(ClientSocket, &readfd))
   {
    if(totalread1<MAXBUFSIZE)
      {
     read1=recv(ClientSocket, read_in1, MAXBUFSIZE-totalread1, 0);
     if((read1==SOCKET_ERROR) || (read1==0))
       {
        break;
       }
     memcpy(send_out1+totalread1,read_in1,read1);
     totalread1+=read1;
     memset(read_in1,0,MAXBUFSIZE);
    }
    if(SendRequest(CSsocket,SenderBuf,send_out1,totalread1))
     totalread1=0;
   }
   if(FD_ISSET(ServerSocket, &writefd))
   {
    int err=0;
    sendcount1=0;
    while(totalread1>0)
    {
     send1=send(ServerSocket, send_out1+sendcount1, totalread1, 0);
     if(send1==0)break;
     if((send1<0) && (errno!=EINTR))
     {
      err=1;
      break;
     }
     if((send1<0) && (errno==ENOSPC)) break;
     sendcount1+=send1;
     totalread1-=send1;
    }
    if(err==1) break;
    if((totalread1>0) && (sendcount1>0))
    {
     memcpy(send_out1,send_out1+sendcount1,totalread1);
     memset(send_out1+totalread1,0,MAXBUFSIZE-totalread1);
    }
    else
    memset(send_out1,0,MAXBUFSIZE);
   }
   Sleep(5);
}
closesocket(ClientSocket);
closesocket(ServerSocket);
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
易语言是一种面向初学者的编程语言,对于网络编程而言,它也提供了一些简单易懂的函数和方法。以下是一个示例的易语言socks5代理源码。 ```easylanguage '引用系统库 AddExtLib("Ws2_32.lib") '定义常量 %BUFFER_SIZE = 4096 '创建Socket对象 sock = sockCreate() '定义代理服务器的地址和端口 proxyAddress = "192.168.0.1" proxyPort = 1080 '定义服务器的地址和端口 serverAddress = "example.com" serverPort = 80 '连接到代理服务器 sock.Connect(proxyAddress, proxyPort) '发送用户名密码认证 username = "your_username" password = "your_password" sock.SendStr(chr(len(username)) + username + chr(len(password)) + password) '从代理服务器接收认证结果 authenticationResult = sock.RecvStr(2) '检查认证结果 if authenticationResult = chr(0) + chr(0) then '认证成功,发送连接请求 sock.SendStr(chr(5) + chr(1) + chr(0) + chr(3) + chr(len(serverAddress)) + serverAddress + chr(serverPort \ 256) + chr(serverPort mod 256)) '接收连接请求结果 connectionResult = sock.RecvStr(4) '检查连接请求结果 if connectionResult = chr(5) + chr(0) + chr(0) + chr(1) then '连接请求成功,开始传输数据 sock.SendStr("GET / HTTP/1.1\r\nHost: " + serverAddress + "\r\n\r\n") '接收响应数据 response = "" while true data = sock.RecvStr(%BUFFER_SIZE) if data = "" then break else response = response + data end if wend '打印响应数据 print(response) '关闭连接 sock.Close() else '连接请求失败,打印错误消息 print("Connection request failed") end if else '认证失败,打印错误消息 print("Authentication failed") end if '销毁Socket对象 sock.Destroy() ``` 以上的代码实现了一个简单的socks5代理客户端,在连接代理服务器后,进行用户身份认证并发送连接请求,然后接收服务器的响应数据并打印出来。需要注意的是,这只是一个简单的示例,实际使用中可能需要根据具体情况进行修改和完善。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值