Работа через socks5

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Ant1b10t1k, 6 Jul 2009.

  1. Ant1b10t1k

    Ant1b10t1k New Member

    Joined:
    18 Jun 2009
    Messages:
    8
    Likes Received:
    1
    Reputations:
    5
    Хочу написать паблик чекер акк. mail.ru через sock5.
    Нашел удобный класс для работы с проксями. После того как я подключился к smtp.mail.ru через проксю, я должен от него получить данные, а потом отправить. Загвоздка в том что я получаю данные и сразу же хост мне lost connection. Все уже пересмотрел ошибок вроде нет. Посмотрите вы пожалуйста. С прокси все нормально. Без проксей все получается, думаю что ошибка в классе а найти не могу помогите.

    Code:
     #include <winsock2.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <iostream>
      using namespace std;
    
      #pragma comment(lib, "Ws2_32.lib")
    
    class CTSocket
    {
        public:
          virtual BOOL CreateSocket();
          virtual BOOL Connect(unsigned long ip, unsigned short port);
          virtual BOOL Connect(LPCSTR name, unsigned short port);
          virtual int Send(const char* str, int len);
          virtual int Recv(char* buf, int max);
          virtual void Close();
          virtual unsigned long GetHost(); // Узнать свой адрес. Это тоже может понадобиться.
    
        private:
          SOCKET sock;
      };
    
      BOOL CTSocket::CreateSocket()
      {
    	   return (sock = socket(AF_INET, SOCK_STREAM, 0)) != NULL;
      }
    
      BOOL CTSocket::Connect(unsigned long ip, unsigned short port)
      {
    	  SOCKADDR_IN addr;
    	  memset(&addr, 0, sizeof(addr));
    	  addr.sin_family = AF_INET;
    	  addr.sin_addr.S_un.S_addr = ip;
    	  addr.sin_port = port;
    	  return connect(sock, (SOCKADDR*)&addr, sizeof(addr)) == 0;
      }
    
      BOOL CTSocket::Connect(LPCSTR name, unsigned short port)
      {
    	  HOSTENT* p = gethostbyname(name);
    	  if (p == NULL) return FALSE;
    	  return Connect(p->h_addr_list[0], port);
      }
    
      int CTSocket::Send(const char* str, int len)
      {
    	  return send(sock, str, len, 0);
      }
    
      int CTSocket::Recv(char* buf, int max)
      {
    	  return recv(sock, buf, max, 0);
      }
    
      void CTSocket::Close()
      {
    	  closesocket(sock);
      }
    
      unsigned long CTSocket::GetHost()
      {
    	  SOCKADDR_IN addr;
    	  int cbName = sizeof(addr);
    	  if (getsockname(sock, (SOCKADDR*)&addr, &cbName) == 0)
    	  {
    		  return addr.sin_addr.S_un.S_addr;
    	  } else return 0;
      }
    
    
      class CSocksSocket : public CTSocket
      {
        public:
          virtual BOOL CreateSocket();
          virtual BOOL Connect(unsigned long ip, unsigned short port);
          virtual BOOL Connect(LPCSTR name, unsigned short port);
          virtual int Send(const char* str, int len);
          virtual int Recv(char* buf, int max);
          virtual void Close();
          virtual unsigned long GetHost();
    
         CTSocket* pSocket;
         unsigned long socks_ip;
         unsigned short socks_port;
    
        private:
          char buffer[512];     // Такого размера точно хватит
          unsigned long l_ip;   // Адрес, возвращаемый функцией GetHost()
      };
    
      // Реализация
      BOOL CSocksSocket::CreateSocket()
      {
         if (!pSocket->CreateSocket()) return FALSE;
    	 if (!pSocket->Connect(socks_ip, socks_port)) return FALSE;
         buffer[0] = 5;  // Ver
         buffer[1] = 1;  // 1 method
         buffer[2] = 0;  // no auth
         pSocket->Send(buffer, 3);
         int n = pSocket->Recv(buffer, 2);
         if (n != 2) return FALSE;
         if (buffer[1] != 0) return FALSE;  // method 0 not supported
         return TRUE;
      }
    
      BOOL CSocksSocket::Connect(unsigned long ip, unsigned short port)
      {
         buffer[0] = 5;  // Ver
         buffer[1] = 1;  // CONNECT
         buffer[2] = 0;  // Reserved
         buffer[3] = 1;  // IPv4
         *((unsigned long*)(buffer + 4)) = ip;
         *((unsigned short*)(buffer + 8)) = port;
         pSocket->Send(buffer, 10);
         int n = pSocket->Recv(buffer, 10);
         if (n != 10) return FALSE;
         if (buffer[1] != 0) return FALSE; // Can't connect
         if (buffer[3] != 1) return FALSE; // Будем требовать, чтобы нам сказали IP, а не что-нибудь другое.
         l_ip = *((unsigned long*)(buffer + 4));
         return TRUE;
      }
    
      BOOL CSocksSocket::Connect(LPCSTR name, unsigned short port)
      {
         buffer[0] = 5;
         buffer[1] = 1;
         buffer[2] = 0;
         buffer[3] = 3;  // Domain name
         int m = strlen(name);
         buffer[4] = m;  // Length byte
         memcpy(buffer+5, name, m); // Копируем строку без завершающего нуля
         *((unsigned short*)(buffer + 5 + m)) = port;
         pSocket->Send(buffer, m + 7);
         int n = pSocket->Recv(buffer, 10);
         if (n != 10) return FALSE;
         if (buffer[1] != 0) return FALSE;
         if (buffer[3] != 1) return FALSE; // Будем требовать, чтобы нам сказали IP, а не что-нибудь другое.
         l_ip = *((unsigned long*)(buffer + 4));
         return TRUE;
      }
    
      int CSocksSocket::Send(const char* str, int len)
      {
         return pSocket->Send(str, len);
      }
    
      int CSocksSocket::Recv(char* buf, int max)
      {
         return pSocket->Recv(buf, max);
      }
    
      void CSocksSocket::Close()
      {
         pSocket->Close();
      }
    
      unsigned long CSocksSocket::GetHost()
      {
         return l_ip;
      }
    
      // Ну, а теперь тестовая прога
    void main()
    {
        WSADATA wsadata;
        CTSocket tsock;
        CSocksSocket ssock;
    	ssock.pSocket = &tsock;
    
        WSAStartup(MAKEWORD(2,2), &wsadata);   
    
        ssock.socks_ip = inet_addr("10.10.7.150"); // Впишите сюда нужный адрес
        ssock.socks_port = htons(1080); // Впишите сюда порт
        
        if (!ssock.CreateSocket()) return;	// Can't connect to socks
    					// or auth required
        if (!ssock.Connect("smtp.mail.ru", htons(2525))) return; // www.mail.ru 
    							  // is inaccessible
        
        char buf[79];
        ssock.Recv(buf, 79);
    
        LPSTR q = "EHLO mail.ru";
        ssock.Send(q, strlen(q));
    
        ssock.Close();
        WSACleanup();
    }
    
    Что получаю от сервака. Отловив сниффером

    Code:
    220 mail.ru ESMTP Mon, 06 Jul 2009 15:39:05 +0400
    421 mx39.mail.ru lost input connection
    EHLO mail.ru