socks5

  1. / Author: LZX   
  2. // E-mail: LZX@qq.com   
  3. // Version: V2.0 (AsyncMode)   
  4. // Purpose: A Proxy works on one port and supports SOCKS v4 && v5 && Http protocol.   
  5. //          The socks proxy request has not supported BIND method yet.   
  6. //          The Http proxy supports three methods:GET(HEAD) POST CONNECT.   
  7. // Test PlatForm: WinXP SP2   
  8. // Compiled On: VC++ 6.0   
  9.    
  10.    
  11. #include <winsock2.h>   
  12. #include <stdio.h>   
  13.    
  14. #pragma comment(lib,"ws2_32")   
  15. #define BUFSIZE 10240   
  16. #define WM_SOCKET (WM_USER+1)   
  17. #define WM_DNS (WM_USER+2)   
  18. #define WM_HOSTRESOLVED (WM_USER+3)   
  19. #define WM_HOSTFAILED (WM_USER+4)   
  20. #define MAX_HOSTNAME    256   
  21. #define LISTENPORT      8080   
  22.    
  23. #define HEADLEN         7   
  24. char ErrorMsg[]="Http/1.1 403 Forbidden\r\n\r\n<body><h1>403 Forbidden</h1></body>";   
  25. char ConnectionEstablished[]="HTTP/1.0 200 OK\r\n\r\n";   
  26. char Username[256]="\0";   
  27. char Password[256]="\0";   
  28.    
  29. struct Socks4Req   
  30. {   
  31.     BYTE Ver;   
  32.     BYTE REP;   
  33.     WORD wPort;   
  34.     DWORD dwIP;   
  35.     BYTE other[1];   
  36. };   
  37.    
  38. struct Socks5Req   
  39. {   
  40.     BYTE Ver;   
  41.     BYTE nMethods;   
  42.     BYTE Methods[255];   
  43. };   
  44.    
  45. struct AuthReq   
  46. {   
  47.     BYTE Ver;   
  48.     BYTE Ulen;   
  49.     BYTE UserPass[1024];   
  50. };   
  51.    
  52. typedef struct   
  53. {   
  54.     BYTE Ver;      // Version Number   
  55.     BYTE CMD;      // 0x01==TCP CONNECT,0x02==TCP BIND,0x03==UDP ASSOCIATE   
  56.     BYTE RSV;   
  57.     BYTE ATYP;   
  58.     BYTE IP_LEN;   
  59.     BYTE szIP;   
  60. }Socks5Info;   
  61.    
  62. typedef struct   
  63. {   
  64.     DWORD dwIP;   
  65.     WORD wPort;   
  66. }IPandPort;   
  67.    
  68. typedef struct   
  69. {   
  70.     BYTE Ver;   
  71.     BYTE REP;   
  72.     BYTE RSV;   
  73.     BYTE ATYP;   
  74.     IPandPort IPandPort;   
  75. }Socks5AnsConn;   
  76.    
  77. typedef struct   
  78. {   
  79.     BYTE RSV[2];   
  80.     BYTE FRAG;   
  81.     BYTE ATYP;   
  82.     IPandPort IPandPort;   
  83.     BYTE DATA;   
  84. }Socks5UDPHead;   
  85. struct SocketInfo   
  86. {   
  87.     SOCKET socks;   
  88.     IPandPort IPandPort;   
  89. };   
  90. typedef struct   
  91. {   
  92.     SocketInfo Local;   
  93.     SocketInfo Client;   
  94.     SocketInfo Server;   
  95. }Socks5Para;   
  96.    
  97. enum{PROXY_UNKNOWN,PROXY_HTTP,PROXY_SOCK4,PROXY_SOCK5};   
  98.    
  99. struct SOCKETINFO //每个代理连接独享的所用到的变量   
  100. {   
  101. ///   
  102.     BYTE IsCorR;   
  103.     BYTE ProxyType;   
  104.     BYTE IsTunnel;   
  105.     BYTE ConnectFlag;   
  106.     BYTE IsTalkOver;   
  107. ///   
  108.     BYTE SocksVer;   
  109.     BYTE IsAuthPassed;   
  110.     BYTE SOCKS_CMD_UDP;   
  111.     SOCKADDR_IN clientaddr;   
  112. ///   
  113.     SOCKET csock;   
  114.     SOCKET rsock;   
  115.     char buf[BUFSIZE+1];   
  116.     HANDLE hGetHost;   
  117.     char IPAddress[MAXGETHOSTSTRUCT];   
  118.     WORD RemotePort;   
  119.     WORD ClientPort;   
  120.     int recvbytes;   
  121.     int sendbytes;   
  122.     BYTE recvdelayed;   
  123.     SOCKETINFO *next;   
  124. };   
  125.    
  126. SOCKETINFO *SocketInfoList=NULL;//链表索引指针   
  127.    
  128. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);   
  129. void ProcessSocketMessage(HWNDUINTWPARAMLPARAM);   
  130.    
  131. BOOL AddSocketInfo(SOCKET sock);   
  132. SOCKETINFO *GetSocketInfo(SOCKET sock);   
  133. void RemoveSocketInfo(SOCKET sock);   
  134.    
  135. void err_quit(char *msg);   
  136. void err_display(char *msg);   
  137. void err_display(int errcode);   
  138.    
  139. int main(int argc, char* argv[])   
  140. //int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE,   
  141. //  LPSTR lpCmdLine, int nCmdShow)   
  142. {   
  143.     DWORD LisPort=LISTENPORT;   
  144.     if(argc>1)   
  145.         LisPort=atoi(argv[1]);   
  146.     if(argc==4)   
  147.     {   
  148.         strcpy(Username,argv[2]);   
  149.         strcpy(Password,argv[3]);   
  150.     }   
  151.     printf("SOCKS v4 && v5 && Http Proxy V2.0 By LZX.\r\nUsage:\n%s ProxyPort (Default port 1080)\n%s ProxyPort Username Password\n",argv[0],argv[0]);   
  152.    
  153.     int retval;   
  154.     WNDCLASS wndclass;   
  155.     wndclass.cbClsExtra = 0;   
  156.     wndclass.cbWndExtra = 0;   
  157.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);   
  158.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);   
  159.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);   
  160.     wndclass.hInstance = NULL;   
  161.     wndclass.lpfnWndProc = (WNDPROC)WndProc;   
  162.     wndclass.lpszClassName = "MyWindowClass";   
  163.     wndclass.lpszMenuName = NULL;   
  164.     wndclass.style = CS_HREDRAW | CS_VREDRAW;   
  165.     if(!RegisterClass(&wndclass)) return -1;   
  166.    
  167.     HWND hWnd = CreateWindow("MyWindowClass""TCP",   
  168.         WS_OVERLAPPEDWINDOW, 0, 0, 600, 300,   
  169.         NULL, (HMENU)NULL, NULL, NULL);   
  170.     if(hWnd == NULL) return -1;   
  171.     //ShowWindow(hWnd, SW_SHOWNORMAL);   
  172.     //UpdateWindow(hWnd);   
  173.    
  174.     WSADATA wsa;   
  175.     if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)   
  176.         return -1;   
  177.    
  178.     // socket()   
  179.     SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);   
  180.     if(listen_sock == INVALID_SOCKET){   
  181.         printf("Create SOCKET error.\n");   
  182.         return 0;   
  183.     }   
  184.    
  185.     // WSAAsyncSelect()   
  186.     retval = WSAAsyncSelect(listen_sock, hWnd,    
  187.         WM_SOCKET, FD_ACCEPT|FD_CLOSE);   
  188.     if(retval == SOCKET_ERROR) {   
  189.         printf("WSAAsyncSelect SOCKET error.\n");   
  190.         return 0;   
  191.     }   
  192.    
  193.     // bind()   
  194.     SOCKADDR_IN serveraddr;   
  195.     ZeroMemory(&serveraddr, sizeof(serveraddr));   
  196.     serveraddr.sin_family = AF_INET;   
  197.     serveraddr.sin_port = htons(LisPort);   
  198.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);   
  199.     retval = bind(listen_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));   
  200.     if(retval == SOCKET_ERROR){   
  201.         printf("bind SOCKET error.\n");   
  202.         return 0;   
  203.     }   
  204.     // listen()   
  205.     retval = listen(listen_sock, SOMAXCONN);   
  206.     if(retval == SOCKET_ERROR){   
  207.         printf("listen SOCKET error.\n");   
  208.         return 0;   
  209.     }   
  210.     printf("Now listening on port: %d\r\n",LisPort);   
  211.    
  212.     MSG msg;   
  213.     while(GetMessage(&msg, 0, 0, 0) > 0){   
  214.         TranslateMessage(&msg);   
  215.         DispatchMessage(&msg);   
  216.     }   
  217.    
  218.     WSACleanup();   
  219.     return msg.wParam;   
  220. }   
  221.    
  222. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,    
  223.     WPARAM wParam, LPARAM lParam)   
  224. {   
  225.     switch(uMsg){   
  226.     case WM_SOCKET:   
  227.         ProcessSocketMessage(hWnd, uMsg, wParam, lParam);   
  228.         return 0;   
  229.     case WM_DNS:   
  230.         if (WSAGETASYNCERROR(lParam))   
  231.             SendMessage(hWnd, WM_SOCKET, wParam, WM_HOSTFAILED);   
  232.         else   
  233.             SendMessage(hWnd, WM_SOCKET, wParam, WM_HOSTRESOLVED);   
  234.         return 0;   
  235.     case WM_DESTROY:   
  236.         PostQuitMessage(0);   
  237.         return 0;   
  238.     }   
  239.    
  240.     return DefWindowProc(hWnd, uMsg, wParam, lParam);   
  241. }   
  242. int CheckRequest(SOCKETINFO *socketinfo) //检查请求类型,返回一个的标志   
  243. {   
  244.     if(!strnicmp(socketinfo->buf,"GET ",4))   
  245.         return 4;   
  246.     else if(!strnicmp(socketinfo->buf,"HEAD ",5)) //Looks like the same with GET   
  247.         return 5;   
  248.     else if(!strnicmp(socketinfo->buf,"POST ",5))   
  249.         return 5;   
  250.     else if(!strnicmp(socketinfo->buf,"CONNECT ",8))   
  251.         return 8;   
  252.    
  253.     Socks5Req *sq;   
  254.     char Method[2]={0x05,0};   
  255.     sq=(Socks5Req *)socketinfo->buf;   
  256.     //printf("%d,%d,%d,%d,%d\n",sq->Ver,sq->nMethods,sq->Methods[0],sq->Methods[1],sq->Methods[2]);   
  257.     if(sq->Ver!=5)   
  258.         return sq->Ver==4?socketinfo->ProxyType=PROXY_SOCK4:0;   
  259.     if((sq->Methods[0]==0)||(sq->Methods[0]==2))//00,无需认证;01,GSSAPI;02,需要用户名和PASSWORD   
  260.     {   
  261.         if(strlen(Username)==0){   
  262.             Method[1]=0x00;   
  263.             socketinfo->IsAuthPassed=true;//不用验证也就是passed   
  264.         }else   
  265.             Method[1]=0x02;   
  266.         if(send(socketinfo->csock,Method,2,0) == SOCKET_ERROR)   
  267.             return 0;   
  268.         socketinfo->recvbytes=socketinfo->sendbytes=0;   
  269.         return socketinfo->ProxyType=PROXY_SOCK5;   
  270.     }else   
  271.         return 0;   
  272. }   
  273. //httpproxy请求中得到主机名和端口   
  274. void GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,WORD *RemotePort)   
  275. {   
  276.     char *fp = ReceiveBuf;   
  277.     for(int i = 0;i < datalen-1 && *fp != ':' && *fp != '\0' && *fp != '\r' && *fp != '/';i++)   
  278.     {   
  279.         HostName[i]=*fp++;   
  280.         if(*fp == ':')   
  281.             *RemotePort=atoi(fp+1);   
  282.         else *RemotePort=80; //没指定端口则是默认的80   
  283.     }   
  284.     HostName[i]='\0';   
  285. }   
  286. char * GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen)   
  287. {   
  288.     for(int i = 0;i < DataLen; i++)   
  289.     {   
  290.         if(ReceiveBuf[i] == '/')   
  291.         {   
  292.             *HostNaneLen = i;   
  293.             return &ReceiveBuf[i];   
  294.         }   
  295.     }   
  296.     return NULL;   
  297. }   
  298. //修改httpproxy请求包,返回修改后需发送的实际字节数,返回0则失败    
  299. int ModifyRequest(char *ReceiveBuf,int *DataLen,int MethodLength, char *HostName, WORD *RemotePort)   
  300. {   
  301.     int HedLen = 0;   
  302.     char TempBuffer[BUFSIZE];   
  303.     if(strncmp(ReceiveBuf+MethodLength,"http://",HEADLEN))   
  304.         return 0;   
  305.    
  306.     strncpy(TempBuffer,ReceiveBuf,MethodLength);   
  307.     char * Getrootfp = GetURLRootPoint(ReceiveBuf+MethodLength+HEADLEN,(*DataLen)-MethodLength-HEADLEN,&HedLen);   
  308.     if(Getrootfp == NULL){   
  309.         return 0;   
  310.     }   
  311.     GetHostNameAndPort(ReceiveBuf+MethodLength+HEADLEN,*DataLen-MethodLength-HEADLEN,HostName,RemotePort);   
  312.    
  313.     memcpy(TempBuffer+MethodLength,Getrootfp,(*DataLen)-MethodLength-HEADLEN-HedLen);   
  314.     memcpy(ReceiveBuf,TempBuffer,(*DataLen)-HEADLEN-HedLen);   
  315.     *DataLen=(*DataLen)-HEADLEN-HedLen;//修改ptr->recvbytes   
  316.     ReceiveBuf[*DataLen]='\0';   
  317.     return *DataLen;   
  318. }   
  319.    
  320. char *DNS(char *HostName)   
  321. {   
  322.     HOSTENT *hostent = NULL;   
  323.     IN_ADDR iaddr;   
  324.     hostent = gethostbyname(HostName);   
  325.     if (hostent == NULL)   
  326.     {   
  327.         return NULL;   
  328.     }   
  329.     iaddr = *((LPIN_ADDR)*hostent->h_addr_list);   
  330.     return inet_ntoa(iaddr);   
  331. }   
  332. //连接到指定的主机端口,   
  333. bool ConnectToRemoteHost(SOCKET *ServerSocket,HWND hWnd, char *HostName,const WORD RemotePort)   
  334. {   
  335.     struct sockaddr_in Server;   
  336.     memset(&Server, 0, sizeof(Server));   
  337.    
  338.     Server.sin_family = AF_INET;   
  339.     Server.sin_port = htons(RemotePort);   
  340.     Server.sin_addr.s_addr = inet_addr(HostName);   
  341.     // Create Socket   
  342.     *ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   
  343.     if (*ServerSocket == INVALID_SOCKET)   
  344.         return false;   
  345.     int retval = WSAAsyncSelect(*ServerSocket, hWnd, WM_SOCKET, FD_CONNECT|FD_CLOSE);   
  346.     //异步WSAConnect,关联其连接成功的消息FD_CONNECT到窗口句柄hWnd   
  347.     if(retval == SOCKET_ERROR)   
  348.         return false;   
  349.     WSAConnect(*ServerSocket, (const SOCKADDR *)&Server,sizeof(Server),NULL,NULL,NULL,NULL);   
  350.    
  351.     return true;   
  352. }   
  353. //socks5代理的身份验证   
  354. int Authentication(SOCKETINFO *socketinfo)   
  355. {   
  356.     char USER[256];   
  357.     char PASS[256];   
  358.     memset(USER,0,sizeof(USER));   
  359.     memset(PASS,0,sizeof(PASS));   
  360.         AuthReq *aq=(AuthReq *)socketinfo->buf;   
  361.     if(aq->Ver!=1)   
  362.         return 0;   
  363.     if((aq->Ulen!=0)&&(aq->Ulen<=256))   
  364.         memcpy(USER,socketinfo->buf+2,aq->Ulen);   
  365.     int PLen=socketinfo->buf[2+aq->Ulen];   
  366.     if((PLen!=0)&&(PLen<=256))   
  367.         memcpy(PASS,socketinfo->buf+3+aq->Ulen,PLen);   
  368.     //printf("USER %s\nPASS %s\n",USER,PASS);   
  369.     //0=login successfully,0xFF=failure;   
  370.     if(!strcmp(Username,USER) && !strcmp(Password,PASS))   
  371.     {   
  372.         socketinfo->buf[1]=0x00;   
  373.         socketinfo->IsAuthPassed=true;   
  374.         //printf("Socks5 Authentication Passed\n");   
  375.     }   
  376.     else   
  377.     {   
  378.         socketinfo->buf[1]=0xFF;   
  379.         //printf("Invalid Password\n");   
  380.     }   
  381.     if(send(socketinfo->csock,socketinfo->buf,2,0) == SOCKET_ERROR)   
  382.         return 0;   
  383.     socketinfo->recvbytes=socketinfo->sendbytes=0;   
  384.        
  385.     return 1;   
  386. }   
  387. //从socks代理请求包中分析出请求的目标主机名和端口,在udp模式中分析后返回真正数据入口点   
  388. int GetAddressAndPort(char *RecvBuf, int ATYP, char *HostName, WORD *RemotePort)   
  389. {   
  390.     DWORD Socks5InfoSize = sizeof(Socks5Info);   
  391.     DWORD dwIndex = 0;   
  392.     Socks4Req *Socks4Request=(Socks4Req *)RecvBuf;   
  393.     Socks5Info *Socks5Request=(Socks5Info *)RecvBuf;   
  394.     memset(HostName,0,MAX_HOSTNAME);   
  395.     struct sockaddr_in in;   
  396.     if(ATYP==2) //Socks v4 !!!   
  397.     {   
  398.         *RemotePort=ntohs(Socks4Request->wPort);   
  399.         if(RecvBuf[4]!=0x00){  //USERID !!   
  400.             in.sin_addr.s_addr = Socks4Request->dwIP;   
  401.             memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));   
  402.         }else   
  403.             memcpy(HostName, (char*)&Socks4Request->other+1,strlen((char*)&Socks4Request->other+1)+1);   
  404.         return 1;   
  405.     }   
  406.    
  407.     //ATYP=0x01代表IP V4地址 0x03代表域名;   
  408.     if((Socks5Request->Ver==5)&&(ATYP==1))   
  409.     {   
  410.         IPandPort *IPP=(IPandPort *)&Socks5Request->IP_LEN;   
  411.         in.sin_addr.S_un.S_addr = IPP->dwIP;   
  412.         memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));   
  413.         *RemotePort = ntohs(IPP->wPort);   
  414.     }   
  415.     else if((Socks5Request->Ver==5)&&(ATYP==3))   
  416.     {   
  417.         memcpy(HostName, &Socks5Request->szIP, Socks5Request->IP_LEN);   
  418.         memcpy(RemotePort, &Socks5Request->szIP+Socks5Request->IP_LEN, 2);   
  419.         *RemotePort=ntohs(*RemotePort);   
  420.     }else if((Socks5Request->Ver==0)&&(Socks5Request->CMD==0)&&(ATYP==1))   
  421.     {   
  422.         IPandPort *IPP=(IPandPort *)&Socks5Request->IP_LEN;   
  423.         in.sin_addr.S_un.S_addr = IPP->dwIP;   
  424.         memcpy(HostName, inet_ntoa(in.sin_addr),strlen(inet_ntoa(in.sin_addr)));   
  425.         *RemotePort = ntohs(IPP->wPort);   
  426.         return 10; //return Data Enter point        
  427.     }else if((Socks5Request->Ver==0)&&(Socks5Request->CMD==0)&&(ATYP==3))   
  428.     {   
  429.         memcpy(HostName, &Socks5Request->szIP, Socks5Request->IP_LEN);   
  430.         memcpy(RemotePort, &Socks5Request->szIP+Socks5Request->IP_LEN, 2);   
  431.         *RemotePort=ntohs(*RemotePort);   
  432.         return 7+Socks5Request->IP_LEN; //return Data Enter point   
  433.     }else   
  434.         return 0;   
  435.    
  436.     return 1;   
  437.    
  438. }   
  439. //Get and return the work mode. 1:TCP CONNECT   3:UDP ASSOCIATE   
  440. int GetProxyInfo(SOCKETINFO *socketinfo, char *HostName, WORD *RemotePort)   
  441. {   
  442.     Socks5Info *Socks5Request=(Socks5Info *)socketinfo->buf;   
  443.    
  444.     if(Socks5Request->Ver == 4)   
  445.         return GetAddressAndPort(socketinfo->buf, 2, HostName, RemotePort);   
  446.            
  447.     //Get IP Type //0x01==IP V4地址 0x03代表域名;0x04代表IP V6地址;not Support   
  448.     if((Socks5Request->ATYP==1)||(Socks5Request->ATYP==3))   
  449.     {   
  450.         if(!GetAddressAndPort(socketinfo->buf, Socks5Request->ATYP, HostName, RemotePort))   
  451.             return 0;   
  452.     }else return 0;   
  453.    
  454.     //Get and return the work mode. 1:TCP CONNECT   3:UDP ASSOCIATE   
  455.     if((Socks5Request->CMD == 1)||(Socks5Request->CMD == 3))   
  456.         return Socks5Request->CMD;   
  457.     return 0;   
  458. }   
  459. //Get local IP   
  460. char *GetInetIP(char *OutIP)   
  461. {   
  462.     // Get host adresses   
  463.     char addr[16];   
  464.     struct hostent * pHost;   
  465.     pHost = gethostbyname("");   
  466.     forint i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )   
  467.     {   
  468.         OutIP[0]=0;   
  469.         forint j = 0; j < pHost->h_length; j++ )   
  470.         {   
  471.             if( j > 0 ) strcat(OutIP,".");   
  472.             sprintf(addr,"%u", (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]);   
  473.             strcat(OutIP,addr);   
  474.         }   
  475.     }   
  476.     return OutIP;   
  477. }   
  478. //本地创建绑定一个udp套接字   
  479. BOOL CreateUDPSocket(Socks5AnsConn *SAC, SOCKET *socks)   
  480. {   
  481.     char szIP[256];   
  482.     struct sockaddr_in  UDPServer;   
  483.     struct sockaddr_in  in;   
  484.     memset(&in,0,sizeof(sockaddr_in));   
  485.     int structsize=sizeof(sockaddr_in);   
  486.     UDPServer.sin_family=AF_INET;   
  487.     UDPServer.sin_addr.s_addr= INADDR_ANY;   
  488.     UDPServer.sin_port=INADDR_ANY;   
  489.     SOCKET Locals = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);   
  490.     if(Locals == SOCKET_ERROR)   
  491.     {   
  492.         //printf("UDP socket create failed.\n");   
  493.         return 0;   
  494.     }   
  495.     if(bind(Locals,(SOCKADDR*)&UDPServer, sizeof(UDPServer)) == SOCKET_ERROR)   
  496.     {   
  497.         //printf("UDP socket bind failed.\n");   
  498.         return 0;   
  499.     }   
  500.     //UINT TimeOut = TIMEOUT;   
  501.     //setsockopt(Locals,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut));   
  502.     *socks = Locals;   
  503.     getsockname(Locals,(struct sockaddr *)&in,&structsize);   
  504.     SAC->IPandPort.dwIP = inet_addr(GetInetIP(szIP));   
  505.     SAC->IPandPort.wPort = in.sin_port;   
  506.     //printf("UDP Bound to %s:%d\r\n", szIP, ntohs(in.sin_port));   
  507.    
  508.     return 1;   
  509. }   
  510. int UDPSend(SOCKET s, char *buff, int nBufSize, struct sockaddr_in *to,int tolen)   
  511. {   
  512.     int nBytesLeft = nBufSize;   
  513.     int idx = 0, nBytes = 0;   
  514.     while(nBytesLeft > 0)   
  515.     {   
  516.         nBytes = sendto(s, &buff[idx], nBytesLeft, 0, (SOCKADDR *)to, tolen);   
  517.         if(nBytes == SOCKET_ERROR)   
  518.         {   
  519.             //printf("Failed to send buffer to socket %d.\r\n", WSAGetLastError());   
  520.             return SOCKET_ERROR;   
  521.         }   
  522.         nBytesLeft -= nBytes;   
  523.         idx += nBytes;   
  524.     }   
  525.     return idx;   
  526. }   
  527. //套接字消息处理函数   
  528. void ProcessSocketMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
  529. {   
  530.     SOCKETINFO *ptr;   
  531.     SOCKET sock;   
  532.     SOCKET client_sock;   
  533.     SOCKADDR_IN clientaddr;   
  534.     struct  sockaddr_in SenderAddr;   
  535.     struct  sockaddr_in UDPClient,UDPServer;   
  536.     int     SenderAddrSize=sizeof(SenderAddr);   
  537.     HOSTENT *hostent;   
  538.     WSABUF DataBuf;   
  539.     DWORD RecvBytes=0,SendBytes=0;   
  540.     DWORD Flags=0;   
  541.     int ProxyFlag,PTYP;   
  542.     int addrlen=sizeof(sockaddr_in);   
  543.     int retval;   
  544.     bool IsTransmit=false;   
  545.     char    HostName[MAX_HOSTNAME];   
  546.     ///   
  547.     Socks4Req Socks4Request;   
  548.     Socks5AnsConn SAC;   
  549.        
  550.     if(WSAGETSELECTERROR(lParam)){   
  551.         //err_display(WSAGETSELECTERROR(lParam));   
  552.         RemoveSocketInfo(wParam);   
  553.         return;   
  554.     }   
  555.    
  556.     switch(WSAGETSELECTEVENT(lParam)){   
  557.     case FD_ACCEPT:   
  558.         addrlen = sizeof(clientaddr);   
  559.         client_sock = accept(wParam, (SOCKADDR *)&clientaddr, &addrlen);   
  560.         if(client_sock == INVALID_SOCKET){   
  561.             if(WSAGetLastError() != WSAEWOULDBLOCK)   
  562.                 //err_display("accept()");   
  563.             return;   
  564.         }   
  565.         //printf("[TCP] Accept IP:%s:%d\n",    
  566.         //  inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));   
  567.         if(!AddSocketInfo(client_sock)){   
  568.             printf("AddSocketInfo error.\n");   
  569.             closesocket(client_sock);   
  570.             return;   
  571.         }   
  572.         retval = WSAAsyncSelect(client_sock, hWnd,    
  573.             WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);   
  574.         if(retval == SOCKET_ERROR){   
  575.             //err_display("WSAAsyncSelect()");   
  576.             RemoveSocketInfo(client_sock);   
  577.         }   
  578.         break;   
  579.     case FD_READ:   
  580.         //printf("SOCKET:%d case FD_READ\n",wParam);   
  581.    
  582.         ptr = GetSocketInfo(wParam);   
  583.         if(!ptr){   
  584.             closesocket(wParam);   
  585.             //printf("ptr==NULL\n");   
  586.             return;   
  587.         }   
  588.         //sock5 udp代理模式的接收和转发处理 START:     
  589.         //需要域名DNS的转发处理仍不理想,即异步WSAAsyncGetHostByName后数据的处理   
  590.         //不用异步WSAAsyncGetHostByName的话没问题,但有些域名的解释可能会花几秒时间,   
  591.         //这样就违背了这个程序的异步模式框架   
  592.         if(wParam==ptr->rsock&&ptr->SOCKS_CMD_UDP){   
  593.             if(ptr->recvdelayed==true){   
  594.                 //printf("case FD_READ: ptr->recvdelayed==true!!!!!!!!!!!\n");   
  595.                 return//WSAAsyncGetHostByName...还没消息,缓冲区数据还未发出,   
  596.                 //所以应该延迟接收数据,但不知道为什么测试qq效果不行,注释掉反而好点   
  597.             }   
  598.             memset(&UDPServer,0,sizeof(sockaddr_in));   
  599.             //DataBuf.buf=ptr->buf+10;  //空出10个字节缓冲区,方便增加转发给Client的udp报头   
  600.             //DataBuf.len=BUFSIZE -10;   
  601.             RecvBytes=recvfrom(ptr->rsock,   
  602.                 ptr->buf+10, BUFSIZE-10, 0, (struct sockaddr FAR *)&SenderAddr, &SenderAddrSize);   
  603.             if(RecvBytes == SOCKET_ERROR){   
  604.                 err_display("recvfrom()");   
  605.                 PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  606.                 printf("WSARecvFrom SOCKET_ERROR\n");   
  607.                 return;   
  608.             }   
  609.             if(SenderAddr.sin_port==ptr->clientaddr.sin_port)   
  610.             {//Data come from client   
  611.                 int retval=GetAddressAndPort(ptr->buf+10, ptr->buf[13], HostName, &ptr->RemotePort);   
  612.                 if(retval)   
  613.                 {   
  614.                     //printf("Data come from client IP: %s:%d | %d Bytes.\n",   
  615.                     //  inet_ntoa(SenderAddr.sin_addr),ntohs(SenderAddr.sin_port),RecvBytes);   
  616.                     //send data to server   
  617.                     //printf("Target IP: %s:%d || DataPoint: %d\n",HostName,ptr->RemotePort,retval);   
  618.                     UDPServer.sin_family=AF_INET;   
  619.                     UDPServer.sin_port=htons(ptr->RemotePort);   
  620.                        
  621.                     if (ptr->buf[13] == 0x03){//域名,需要dns,   
  622.                         //异步WSAAsyncGetHostByName   
  623.                         /*printf("recvdelayed=true,WSAAsyncGetHostByName...\n");  
  624.                         ptr->recvbytes=RecvBytes;  
  625.                         ptr->sendbytes=retval;  
  626.                         ptr->recvdelayed=true;  
  627.                         ptr->hGetHost=WSAAsyncGetHostByName(hWnd, WM_DNS , HostName, ptr->IPAddress, MAXGETHOSTSTRUCT);  
  628.                         return;*/   
  629.                         UDPServer.sin_addr.s_addr = inet_addr(DNS(HostName));//同步的域名解析   
  630.                     }else   
  631.                         UDPServer.sin_addr.s_addr = inet_addr(HostName);   
  632.                     if(UDPSend(ptr->rsock,ptr->buf+retval+10, RecvBytes-retval,&UDPServer,sizeof(UDPServer)) == SOCKET_ERROR)   
  633.                     {   
  634.                         //printf("sendto server error!!!!\n");   
  635.                         PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  636.                     }   
  637.                     //printf("Data(%d) sent to server succeed.\n",RecvBytes-retval);   
  638.                 }else{   
  639.                     //printf("GetAddressAndPort error\n");   
  640.                     PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  641.                     return;   
  642.                 }   
  643.             }else   
  644.             {//Data come from server   
  645.                 //printf("Data come from server IP: %s:%d | %d Bytes.\n",   
  646.                 //      inet_ntoa(SenderAddr.sin_addr),ntohs(SenderAddr.sin_port),RecvBytes);   
  647.                 Socks5UDPHead *UDPHead = (Socks5UDPHead*)ptr->buf;   
  648.                 memset(UDPHead,0,10);   
  649.                 UDPHead->ATYP=0x01;   
  650.                 //UDPHead->IPandPort=sPara->Client.IPandPort;   
  651.                 UDPHead->IPandPort.dwIP =ptr->clientaddr.sin_addr.S_un.S_addr;   
  652.                 UDPHead->IPandPort.wPort=ptr->clientaddr.sin_port;   
  653.                 //memcpy(&UDPHead->DATA-2,RecvBuf,DataLength);//UDPHead->DATA-2!!!!!!!!!!!!   
  654.                    
  655.                 if(UDPSend(ptr->rsock,ptr->buf,RecvBytes+10,&ptr->clientaddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR)   
  656.                 {   
  657.                     //printf("sendto client error!!!!!!!!!!\n");   
  658.                     PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  659.                     return;   
  660.                 }   
  661.                 //printf("sendto client ok\n");   
  662.             }   
  663.             break;   
  664.         }sock5 udp代理模式的接收和转发处理   END!   
  665.            
  666.         //sock5 tcp代理模式的接收和转发处理   start   
  667.         sock=ptr->IsCorR?ptr->csock:ptr->rsock;   
  668.         if(ptr->recvbytes > 0){   
  669.             //printf("SOCKET: %d recvdelayed = TRUE\n", wParam);   
  670.             ptr->recvdelayed = TRUE;   
  671.             //PostMessage(hWnd, WM_SOCKET, ptr->IsCorR?ptr->rsock:ptr->csock, FD_WRITE);   
  672.             return;   
  673.         }   
  674.    
  675.         DataBuf.buf=ptr->buf;   
  676.         DataBuf.len=BUFSIZE;   
  677.         //retval = recv(sock, ptr->buf, BUFSIZE, 0);   
  678.         if(WSARecv(sock, &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR){   
  679.             if(WSAGetLastError() != WSAEWOULDBLOCK){   
  680.                 //err_display("recv()");   
  681.                 RemoveSocketInfo(wParam);   
  682.             }   
  683.             return;   
  684.         }   
  685.         ptr->recvbytes = RecvBytes;   
  686.         ptr->buf[RecvBytes] = '\0';   
  687.         //addrlen = sizeof(clientaddr);   
  688.         //getpeername(wParam, (SOCKADDR *)&ptr->clientaddr, &addrlen);   
  689.         //if(ptr->IsCorR && !ptr->IsTunnel)   
  690.         //printf("[TCP/%s:%d] \n%s\n", inet_ntoa(clientaddr.sin_addr),   
  691.         //  ntohs(clientaddr.sin_port), ptr->buf);   
  692.         //接收到的数据是来自client并且还没进入纯转发模式(如http connect 代理模式以及socks5还没通过所有协议对话)   
  693.         if(ptr->IsCorR && !ptr->IsTunnel)   
  694.         {   
  695.             //ptr->IsTalkOver=false; //该结构new创建后memset清零了,已经是false,所以注释掉无所谓   
  696.             if(ptr->ProxyType==PROXY_SOCK5 && ptr->IsAuthPassed)//代理类型是sock5而且已经通过身份验证   
  697.             {   
  698.                 PTYP = GetProxyInfo(ptr, HostName, &ptr->RemotePort);//分析获得代理信息(目标IP和端口,代理模式)   
  699.                 if(PTYP==1){//1:TCP CONNECT 模式   
  700.                     //printf("GetProxyInfo: %s:%d\n",HostName, &ptr->RemotePort);   
  701.                     if (inet_addr(HostName) == INADDR_NONE)//HostName是域名的情况下要DNS   
  702.                         ptr->hGetHost=WSAAsyncGetHostByName(hWnd, WM_DNS , HostName, ptr->IPAddress, MAXGETHOSTSTRUCT);   
  703.                     else{   
  704.                         retval = ConnectToRemoteHost(&ptr->rsock, hWnd, HostName, ptr->RemotePort);//连接目标   
  705.                         if(!retval)   
  706.                             RemoveSocketInfo(wParam);   
  707.                     }   
  708.                     break;   
  709.                 }else if(PTYP==3)//3:UDP ASSOCIATE 模式   
  710.                 {   
  711.                     ptr->ClientPort = ptr->RemotePort;   
  712.                     getpeername(ptr->csock, (SOCKADDR *)&ptr->clientaddr, &addrlen);   
  713.                     ptr->clientaddr.sin_port=htons(ptr->ClientPort);   
  714.                     memset(&SAC,0,sizeof(SAC));   
  715.                     if(!CreateUDPSocket(&SAC,&ptr->rsock)) //Create a local UDP socket   
  716.                         SAC.REP=0x01;   
  717.                     SAC.Ver=5;   
  718.                     SAC.ATYP=1;   
  719.                     if(send(ptr->csock, (char *)&SAC, 10, 0) == SOCKET_ERROR)//After Create a local UDP socket successfully,reply client is ready.   
  720.                         PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  721.                     retval = WSAAsyncSelect(ptr->rsock, hWnd, WM_SOCKET, FD_READ|FD_CLOSE);   
  722.                     if(retval == SOCKET_ERROR){   
  723.                         PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  724.                     }   
  725.                     ptr->SOCKS_CMD_UDP=true;   
  726.                     break;   
  727.                 }else   
  728.                     PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  729.                 break;   
  730.             }else if(ptr->ProxyType==PROXY_SOCK5 && !ptr->IsAuthPassed)   
  731.             {   
  732.                 Authentication(ptr);///!!!sock5代理模式,!ptr->IsAuthPassed则验证之   
  733.                 break;   
  734.             }   
  735.             ProxyFlag=CheckRequest(ptr);//检查请求包头,分析代理类型   
  736.             if(!ProxyFlag){//不可识别   
  737.                 //printf("!HTTPProxyFlag\n");   
  738.                 if(!ptr->ProxyType){//且代理类型仍不明,也就是首次的请求,前请求不可识别   
  739.                 RemoveSocketInfo(wParam);//非法请求,关闭   
  740.                 return;   
  741.                 }   
  742.             }else if(ProxyFlag==4||ProxyFlag==5) // "get "==4,"head "=="post "==5    
  743.             {   
  744.                 ptr->ProxyType=PROXY_HTTP;   
  745.                 if(!ModifyRequest(ptr->buf,&ptr->recvbytes,ProxyFlag,HostName,&ptr->RemotePort)){//获取http代理请求中的目标主机和端口并修改该包   
  746.                     printf("!ModifyRequest\n");   
  747.                     RemoveSocketInfo(wParam);   
  748.                     return;   
  749.                 }   
  750.                 //http代理的非connect模式的,标志协议对话完毕   
  751.                 ptr->IsTalkOver=true;   
  752.             }else if(ProxyFlag==8)//http proxy "connect " mode =8   
  753.             {   
  754.                 ptr->ProxyType=PROXY_HTTP;   
  755.                 GetHostNameAndPort(ptr->buf+ProxyFlag,ptr->recvbytes-ProxyFlag-HEADLEN,HostName,&ptr->RemotePort);   
  756.             }else if(ProxyFlag==PROXY_SOCK4)//socks4代理,第一个包就带请求目的ip和端口信息了   
  757.             {   
  758.                 ptr->IsAuthPassed=true;//socks4不支持验证,也就是通过了   
  759.                 PTYP = GetProxyInfo(ptr, HostName, &ptr->RemotePort);//分析获取代理信息:IP AND PORT   
  760.                 if(PTYP){   
  761.                     //printf("GetProxyInfo: %s:%d\n",HostName, &ptr->RemotePort);   
  762.                     if (inet_addr(HostName) == INADDR_NONE)   
  763.                         ptr->hGetHost=WSAAsyncGetHostByName(hWnd, WM_DNS , HostName, ptr->IPAddress, MAXGETHOSTSTRUCT);   
  764.                     else{   
  765.                         retval = ConnectToRemoteHost(&ptr->rsock, hWnd, HostName, ptr->RemotePort);   
  766.                         if(!retval)   
  767.                             RemoveSocketInfo(wParam);   
  768.                     }   
  769.                 }   
  770.                 break;   
  771.             }   
  772.    
  773.             if(ptr->ProxyType==PROXY_HTTP)//http 代理,dns主机名后连接目标主机   
  774.             {   
  775.             ptr->ConnectFlag=false;//标志为远程主机未连接   
  776.             //printf("ConnectToRemoteHost=>%s:%d\n", HostName, ptr->RemotePort);   
  777.             if (inet_addr(HostName) == INADDR_NONE)//DNS   
  778.                 ptr->hGetHost=WSAAsyncGetHostByName(hWnd, WM_DNS , HostName, ptr->IPAddress, MAXGETHOSTSTRUCT);   
  779.             else{   
  780.                 retval = ConnectToRemoteHost(&ptr->rsock, hWnd, HostName, ptr->RemotePort);   
  781.                 if(!retval)   
  782.                     RemoveSocketInfo(wParam);   
  783.                 }   
  784.                
  785.             break;   
  786.             }   
  787.         }   
  788.         IsTransmit=true;//所有FD_READ之后缓冲区的数据都要转发到目的地   
  789.     case FD_WRITE:   
  790.    
  791.         //printf("SOCKET: %d case FD_WRITE\n",wParam);   
  792.         ptr = GetSocketInfo(wParam);   
  793.         if(!ptr){   
  794.             closesocket(wParam);   
  795.             //printf("ptr==NULL\n",wParam);   
  796.             return;   
  797.         }   
  798.         if(IsTransmit) //是要转发的话,如果wParam是客户端套接字则设sock为远程端的套接字,反之亦然,否则sock仍为当前wParam值   
  799.             sock=ptr->IsCorR?ptr->rsock:ptr->csock;   
  800.         else   
  801.             sock=ptr->IsCorR?ptr->csock:ptr->rsock;   
  802.    
  803.         if(ptr->recvbytes <= ptr->sendbytes || !ptr->IsTalkOver || !ptr->ConnectFlag)//协议对话完毕且目的IP连接已经标志才进行数据转发   
  804.             return;   
  805.    
  806.         //开始发送缓冲区数据   
  807.         //if(ptr->rsock==sock && !ptr->IsTunnel)   
  808.         //  printf("Send: \n%s\n",ptr->buf);   
  809.         //retval = send(sock, ptr->buf + ptr->sendbytes,    
  810.         //  ptr->recvbytes - ptr->sendbytes, 0);   
  811.         DataBuf.buf=ptr->buf + ptr->sendbytes;   
  812.         DataBuf.len=ptr->recvbytes - ptr->sendbytes;   
  813.         if(WSASend(sock, &DataBuf, 1, &SendBytes, Flags, NULL, NULL)== SOCKET_ERROR){   
  814.             if(WSAGetLastError() != WSAEWOULDBLOCK){   
  815.                 //err_display("send()");   
  816.                 RemoveSocketInfo(wParam);   
  817.             }   
  818.             return;   
  819.         }   
  820.         ptr->sendbytes += SendBytes;   
  821.         if(ptr->recvbytes == ptr->sendbytes){   
  822.             ptr->recvbytes = ptr->sendbytes = 0;   
  823.             if(ptr->recvdelayed){   
  824.                 ptr->recvdelayed = FALSE;   
  825.                 //printf("ptr->recvdelayed = FALSE\n");   
  826.                 PostMessage(hWnd, WM_SOCKET, sock==ptr->csock?ptr->rsock:ptr->csock, FD_READ);   
  827.             }   
  828.         }   
  829.         break;   
  830.     case FD_CONNECT://ConnectToRemoteHost的结果,目标连接成功   
  831.         ptr = GetSocketInfo(wParam);   
  832.         if(!ptr){   
  833.             //printf("ptr==NULL\n",wParam);   
  834.             return;   
  835.         }   
  836.         ptr->ConnectFlag=true;//标志为已连接   
  837.         WSAAsyncSelect(wParam, hWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);//关联该套接字的读写和关闭消息到窗口   
  838.            
  839.         //printf("Connect To Remote Host OK\n");   
  840.         if(!ptr->IsTalkOver&&ptr->ProxyType==PROXY_HTTP){//http代理类型如果在连接目标后IsTalkOver仍未标志,则表示是connect模式   
  841.             DataBuf.buf=ConnectionEstablished;   
  842.             DataBuf.len=strlen(ConnectionEstablished)+1;//最后一个协议对话,即回复客户端目标连接 ready   
  843.             if(WSASend(ptr->csock, &DataBuf, 1, &SendBytes, Flags, NULL, NULL)== SOCKET_ERROR){   
  844.                 if(WSAGetLastError() != WSAEWOULDBLOCK){   
  845.                     //err_display("send()");   
  846.                     RemoveSocketInfo(wParam);   
  847.                 }   
  848.                 return;   
  849.             }   
  850.             ptr->IsTalkOver=true;//标志协议对话完毕   
  851.             ptr->IsTunnel=true;//已经可以进入纯转发模式   
  852.             ptr->recvbytes = ptr->sendbytes = 0;   
  853.         }else if(!ptr->IsTalkOver&&ptr->ProxyType==PROXY_SOCK5)//socks5代理在连接目标后回复客户端ready   
  854.         {   
  855.             memset(&SAC,0,sizeof(SAC));   
  856.             SAC.Ver=0x05;   
  857.             SAC.ATYP=0x01;   
  858.             if(send(ptr->csock, (char *)&SAC, 10, 0) == SOCKET_ERROR)   
  859.                 PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  860.             ptr->recvbytes=ptr->sendbytes=0;   
  861.             ptr->IsTalkOver=true;//标志协议对话完毕   
  862.             ptr->IsTunnel=true;//已经可以进入纯转发模式   
  863.         }else if(!ptr->IsTalkOver&&ptr->ProxyType==PROXY_SOCK4)//socks4 同socks5    
  864.         {   
  865.             memset(&Socks4Request, 0, 9);   
  866.             Socks4Request.REP = 0x5A; //GRANT   
  867.             if(send(ptr->csock, (char *)&Socks4Request, 8, 0) == SOCKET_ERROR)   
  868.                 PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  869.             ptr->recvbytes=ptr->sendbytes=0;   
  870.             ptr->IsTalkOver=true;   
  871.             ptr->IsTunnel=true;   
  872.         }   
  873.         break;   
  874.     case WM_HOSTRESOLVED://异步WSAAsyncGetHostByName成功的结果   
  875.            
  876.         ptr = SocketInfoList;   
  877.         while(ptr){   
  878.             if(ptr->hGetHost==(HANDLE)wParam)   
  879.                 break;   
  880.             ptr = ptr->next;   
  881.         }   
  882.         if(!ptr){   
  883.             //printf("ptr==NULL\n",wParam);   
  884.             return;   
  885.         }   
  886.         hostent=(HOSTENT*)ptr->IPAddress;   
  887.         //printf("WM_HOSTRESOLVED:%s:%d\n",inet_ntoa(*((LPIN_ADDR)*hostent->h_addr_list)),ptr->RemotePort);   
  888.         if(ptr->SOCKS_CMD_UDP)//socks5 udp模式代理(面向非连接协议)所以在dns后不用connect就可以直接转发数据   
  889.         {   
  890.             memset(&UDPServer,0,sizeof(UDPServer));   
  891.             UDPServer.sin_family=AF_INET;   
  892.             UDPServer.sin_port=htons(ptr->RemotePort);   
  893.             UDPServer.sin_addr.s_addr= inet_addr(inet_ntoa(*((LPIN_ADDR)*hostent->h_addr_list)));   
  894.             if(UDPSend(ptr->rsock,ptr->buf+ptr->sendbytes+10, ptr->recvbytes-ptr->sendbytes,&UDPServer,sizeof(UDPServer)) == SOCKET_ERROR)   
  895.             {   
  896.                 //printf("WM_HOSTRESOLVED sendto server error!!!!\n");   
  897.                 PostMessage(hWnd, WM_SOCKET, ptr->csock, FD_CLOSE);   
  898.             }   
  899.             //printf("WM_HOSTRESOLVED sendto server success!!!!\n");   
  900.             ptr->recvdelayed=ptr->sendbytes=ptr->recvbytes=0;   
  901.             break;   
  902.         }   
  903.         retval = ConnectToRemoteHost(&ptr->rsock, hWnd, inet_ntoa(*((LPIN_ADDR)*hostent->h_addr_list)), ptr->RemotePort);   
  904.         if(!retval)   
  905.             RemoveSocketInfo(ptr->csock);   
  906.         break;   
  907.     case WM_HOSTFAILED://dns 失败消息   
  908.         ptr = SocketInfoList;   
  909.         while(ptr){   
  910.             if(ptr->hGetHost==(HANDLE)wParam)   
  911.                 break;   
  912.             ptr = ptr->next;   
  913.         }   
  914.         if(ptr){   
  915.             RemoveSocketInfo(ptr->csock);   
  916.         }   
  917.         break;   
  918.     case FD_CLOSE:   
  919.         RemoveSocketInfo(wParam);   
  920.         break;   
  921.         }   
  922. }   
  923. //将新的请求的套接字信息加到此链中   
  924. BOOL AddSocketInfo(SOCKET sock)   
  925. {   
  926.     SOCKETINFO *ptr = new SOCKETINFO;   
  927.     if(ptr == NULL){   
  928.         printf("new SOCKETINFO error!\n");   
  929.         return FALSE;   
  930.     }   
  931.     memset(ptr,0,sizeof(SOCKETINFO));   
  932.     //ptr->ProxyType = PROXY_UNKNOWN;   
  933.     ptr->csock = sock;   
  934.     //ptr->recvbytes = 0;   
  935.     //ptr->sendbytes = 0;   
  936.     //ptr->recvdelayed = FALSE;   
  937.     ptr->next = SocketInfoList;   
  938.     SocketInfoList = ptr;   
  939.    
  940.     return TRUE;   
  941. }   
  942. //从SOCKETINFO链中获得指定套接字的指针   
  943. SOCKETINFO *GetSocketInfo(SOCKET sock)   
  944. {   
  945.     SOCKETINFO *ptr = SocketInfoList;   
  946.    
  947.     while(ptr){   
  948.         if(ptr->csock == sock||ptr->rsock == sock)   
  949.         {   
  950.             ptr->IsCorR=(ptr->csock == sock)?true:false;   
  951.             return ptr;   
  952.         }   
  953.         ptr = ptr->next;   
  954.     }   
  955.    
  956.     return NULL;   
  957. }   
  958. //从SOCKETINFO链中删除指定套接字的指针   
  959. void RemoveSocketInfo(SOCKET sock)   
  960. {   
  961.     //SOCKADDR_IN clientaddr;   
  962.     //int addrlen = sizeof(clientaddr);   
  963.     //getpeername(sock, (SOCKADDR *)&clientaddr, &addrlen);   
  964.     //printf("[Close] IP:%s:%d\n",    
  965.     //  inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));   
  966.    
  967.     SOCKETINFO *curr = SocketInfoList;   
  968.     SOCKETINFO *prev = NULL;   
  969.    
  970.     while(curr){   
  971.         if(curr->csock == sock||curr->rsock == sock){   
  972.             if(prev)   
  973.                 prev->next = curr->next;   
  974.             else   
  975.                 SocketInfoList = curr->next;   
  976.             closesocket(curr->csock);   
  977.             closesocket(curr->rsock);   
  978.             delete curr;   
  979.             return;   
  980.         }   
  981.         prev = curr;   
  982.         curr = curr->next;   
  983.     }   
  984. }   
  985.    
  986. void err_quit(char *msg)   
  987. {   
  988.     /*  
  989.     LPVOID lpMsgBuf;  
  990.     FormatMessage(   
  991.         FORMAT_MESSAGE_ALLOCATE_BUFFER|  
  992.         FORMAT_MESSAGE_FROM_SYSTEM,  
  993.         NULL, WSAGetLastError(),  
  994.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  
  995.         (LPTSTR)&lpMsgBuf, 0, NULL);  
  996.     MessageBox(NULL, (LPCTSTR)lpMsgBuf, msg, MB_ICONERROR);  
  997.     LocalFree(lpMsgBuf);  
  998.     exit(-1);  
  999.     */   
  1000.     printf("%s\n",msg);   
  1001. }   
  1002.    
  1003. void err_display(char *msg)   
  1004. {   
  1005.     LPVOID lpMsgBuf;   
  1006.     FormatMessage(    
  1007.         FORMAT_MESSAGE_ALLOCATE_BUFFER|   
  1008.         FORMAT_MESSAGE_FROM_SYSTEM,   
  1009.         NULL, WSAGetLastError(),   
  1010.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   
  1011.         (LPTSTR)&lpMsgBuf, 0, NULL);   
  1012.     printf("[%s] %s", msg, (LPCTSTR)lpMsgBuf);   
  1013.     LocalFree(lpMsgBuf);   
  1014.     printf("%s\n",msg);   
  1015. }   
  1016.    
  1017. void err_display(int errcode)   
  1018. {   
  1019.     LPVOID lpMsgBuf;   
  1020.     FormatMessage(    
  1021.         FORMAT_MESSAGE_ALLOCATE_BUFFER|   
  1022.         FORMAT_MESSAGE_FROM_SYSTEM,   
  1023.         NULL, errcode,   
  1024.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   
  1025.         (LPTSTR)&lpMsgBuf, 0, NULL);   
  1026.     printf("[Error] %s", (LPCTSTR)lpMsgBuf);   
  1027.     LocalFree(lpMsgBuf);   
  1028. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值