A
Antonim
Всем привет!
Я хочу реализовать некую программку, которая бы туннелировала трафик приложений, запущенных на машине, через SOCKS v4/v5...
Получая адрес и порт назначения(куда, кто из приложений желает попасть) из функций GetExtendedTcpTable и GetExtendedUdpTable, желаю перенаправить все запросы приложений/ия через прокси, а точнее через цепь прокси серверов.
Позаимствовав небольшой пример подобного соксирования, из журнала Хакер ( bY Николай (G)) , начал реализацию и столкнулся с проблемой коннекта ко второй и последующим соксЯм.
Для начала приведу часть кода(сам туннель):
C++:
///////////////////структуры и константы
#define CONNECT_ERROR 1
#define REQUEST_ERROR 2
#define SOCKS_*цензура* 0xFF
typedef struct _server {
DWORD ip;
u_short port;
} server;
typedef struct _req {
BYTE ver;
BYTE cmd;
BYTE rsv;
BYTE type;
DWORD addr;
u_short port;
} req;
//////////////////////////////////////////////////
int connectbysocks(server *socks, int socksnum, SOCKET s, server dest)
{
SOCKADDR_IN addr;
int nrecv = 0;
char* request = "\x05\x01\x00"; //запрос к проксе
BYTE request_ans[3]; //ответ прокси
req temp;
addr.sin_addr.S_un.S_addr = socks[0].ip;
addr.sin_port = socks[0].port;
addr.sin_family = AF_INET;
if(connect(s, (struct sockaddr *)&addr,sizeof(SOCKADDR_IN))) // к первой прокси
{
return CONNECT_ERROR;
}
for (int i = 1; i <= socksnum; i++) // запросы на 2,3... прокси
{
send(s,(char*)request,3,0);
nrecv = recv(s,(char*)request_ans,3,0);
if (nrecv == SOCKET_ERROR)
{
return REQUEST_ERROR; //ошибка сокета
}
if (request_ans[1]==0xFF)
{
return SOCKS_ERROR; //сервер не ответил или нельзя подключиться
}
if (request_ans[0]!=0x05)
{
return REQUEST_ERROR; // сокси не 5й версии
}
temp.ver = 0x05; //новый запрос - версия и т.д.
temp.cmd = 0x01;
temp.rsv = 0x00;
temp.type = 0x01;
if (i == socksnum) //если дошли до конца то теперь коннект к адресу назначения
{
temp.addr = dest.ip;
temp.port = dest.port;
}
else //иначе след. прокси
{
temp.addr = socks[i].ip;
temp.port = socks[i].port;
}
// printf("Iteration - %d\nsocksaddr - %s\nsockport - %d",i,gi_ntoa(temp.addr),temp.port);
if (!temp.addr) //проблемы с адресом прокси... пропускать
{
continue;
}
send(s,(char*)&temp,sizeof(temp),0); //отправка нового запроса на след прокси
nrecv = recv(s, (char*)&temp,sizeof(temp),0);
if (nrecv == SOCKET_ERROR) // аналогичные проверки
{
return REQUEST_ERROR;
}
if (temp.rsv != 0)
{
return REQUEST_ERROR;
}
if( temp.cmd != 0)
{
return SOCKS_ERROR;
}
}
return 0;
}
в main():
C++:
#define SOCKSNUM 3 //пусть проксей будет 3
int main(int argc, char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
server socks[SOCKSNUM];
server dest;
socks[0].ip = resolve("85.169.47.254");
socks[0].port = htons(28777);
socks[1].ip = resolve("86.101.58.87");
socks[1].port = htons(45957);
socks[2].ip = resolve("94.213.100.187");
socks[2].port = htons(55247);
dest.ip = resolve("ya.ru");
dest.port = htons(80);
SOCKET s = socket (AF_INET,SOCK_STREAM,0);
if (connectbysocks((server*)&socks[0], SOCKSNUM, s, dest))
{
return 0;
}
/// тут блок не по теме
closesocket(s);
WSACleanup();
/* if(_CrtDumpMemoryLeaks())
gprintf(FOREGROUND_RED|FOREGROUND_INTENSITY,
" !!!Îáíàðóæåíû óòå÷êè ïàìÿòè!!! \n");
*/ return 0;
}
...Мне кажется проблема в том что структуру SOCKADDR_IN надо тоже менять на айпи 2ой и следующих прокси, или нет(не получится ли в таком случае просто коннект от моей машины проксе №2 и т.д., а не по цепи)??
P.S.: Скорее всего вопрос избит донЕльзя, но кому не лень посоветуйте как правильнее реализовать такую задачу.
добавил окно с логом...