Доброго времени суток.
Есть программа, она работает с сетью напрямую(нет настройки Socks Proxy). Хочу научить ее идти в Интернет через Socks proxy. Что для этого делаю:
1) подгружаю свою DLL
2) перехватываю connect
Проблема следующая: connect() перехватываю. Если удаленный порт в списке портов, которые нужно отправлять через SOCKS-proxy, то подключаюсь к Socks-proxy, договариваюсь о методе авторизации с ним, отправляю запрос на подключение на remote_ip:port. Все это корректно выполняется. После меняю параметр sockaddr_in, в которых указываю sin_addr и sin_port на Socks-proxy(А нужно ли ?). А как после этого быть? Что вернуть? Соединение с Socks-proxy уже настроено и он ожидает траффика. Если вызвать Real_connect() с измененными sockaddr_in(в моем случае параметр name), то система же откроет новое подключение с Socks-proxy, а этого мне не надо
Вот код:
struct PORTS
{
USHORT *ports;
int size;
};
// Порты, которые нужно отправлять через Socks-proxy
PORTS PortsWithSocks;
static int WSAAPI Catch_connect(SOCKET s, const sockaddr * name, int namelen)
{
if ( ((sockaddr_in *)name)->sin_addr.S_un.S_addr == inet_addr("127.0.0.1"))
return Real_connect(s, name, namelen);
if (MODE == MODE_SOCKS)
{
if (PortsWithSocks.size == 0)
return Real_connect(s, name, namelen);
USHORT port = ((sockaddr_in *)name)->sin_port;
int i, size = PortsWithSocks.size;
// Есть ли port в списке портов для перехвата
for (i = 0; i < size; i++)
{
if (PortsWithSocks.ports[i] == port)
break;
}
if (i == size) // port нет в списке, будет соединение напрямую.
return Real_connect(s, name, namelen);
// Вытащили IP куда необходимо было подключиться и поместили в def_host
char *ptr = inet_ntoa(((sockaddr_in *)name)->sin_addr);
char def_host[17];
strncpy(def_host, ptr,16);
// Создали SOCKET
SOCKET sock = CreateSock();
if (sock == INVALID_SOCKET){
#ifdef MY_DEBUG
MessageBox(NULL,"CreateSock() failed. connect() with default params!!!", "-err", MB_ICONERROR);
#endif
return Real_connect(s, name, namelen);
}
int err;
// Пытаемся подключиться к SOCKS proxy socks_server:socks_port
err = ConnectSock(sock, socks_server, socks_port);
if (err != 0){
#ifdef MY_DEBUG
MessageBox(NULL,"ConnectSock() failed. connect() with default params!!!", "-err", MB_ICONERROR);
#endif
return Real_connect(s, name, namelen);
}
// Выбираем метод авторизации и проходим ее.
err = SendAndChooseAuthMethod(sock, TRUE, login, password);
if (err != PROXYERROR_AUTHGRANTED && err != PROXYERROR_AUTHNOREQUIRED){
#ifdef MY_DEBUG
MessageBox(NULL,"SendAndChooseAuthMethod() failed. connect() with default params!!!", "-err", MB_ICONERROR);
#endif
return Real_connect(s, name, namelen);
}
// Запрос на подключение на def_host:port
err = ConnectionRequest(sock, def_host, ntohs(port));
if (err != PROXYERROR_CONNECTION_ESTABLISHED){
#ifdef MY_DEBUG
MessageBox(NULL,"ConnectionRequest() failed. connect() with default params!!!", "-err", MB_ICONERROR);
#endif
return Real_connect(s, name, namelen);
}
// Нужно ли это ?
((sockaddr_in *)name)->sin_port = socks_port;
((sockaddr_in *)name)->sin_addr.S_un.S_addr = inet_addr(socks_server);
// Необходимо же заменить s = sock; ?
/*s = sock;
WSASetLastError(0);
*/
// Что вернуть?
//return Real_connect(s, name, namelen);
//return 0;
}