PDA

Просмотр полной версии : Работа через socks5


Ant1b10t1k
06.07.2009, 18:41
Хочу написать паблик чекер акк. mail.ru через sock5.
Нашел удобный класс для работы с проксями. После того как я подключился к smtp.mail.ru через проксю, я должен от него получить данные, а потом отправить. Загвоздка в том что я получаю данные и сразу же хост мне lost connection. Все уже пересмотрел ошибок вроде нет. Посмотрите вы пожалуйста. С прокси все нормально. Без проксей все получается, думаю что ошибка в классе а найти не могу помогите.


#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();
}


Что получаю от сервака. Отловив сниффером


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