Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [HELP] delphi+winsock+socks5 (https://forum.antichat.xyz/showthread.php?t=178458)

rikko 13.02.2010 02:45

[HELP] delphi+winsock+socks5
 
Приветствую, господа!
вопрос относительно организации прокси соединения через socks5 на winsocks.
реализовал алгоритм:
1. шлю запрос на sock5 порт
2. получаю ответ сервера (подтвержение соединения)
3. шлю куда хочу коннектиться (например www.google.com:80)
4. получаю ответ, что соединение установлено
5. шлю данные серверу:

GET / HTTP1.1+#13#10+
Host: www.google.com+#13#10#13#10

вот тут непонятки - очень редко когда приходит "200 OK", в основном приходит 400 ошибка, из 1к собранных socks5 примерно половина устанавливает соединение с сервером (остальные недоступны по таймауту), но не понятно как посылают данные ошибка 400 - очень часто приходит. 200 OK бывает очень редко - примерно 10 проксей из этих 1к.
Собственно, что делаю неправильно? почему получается ошибка 400? и почему все же иногда получаю таки 200 ОК? уже запарился голову ломать.

AlexTheC0d3r 13.02.2010 09:12

Цитата:

Сообщение от rikko
Приветствую, господа!
вопрос относительно организации прокси соединения через socks5 на winsocks.
реализовал алгоритм:
1. шлю запрос на sock5 порт
2. получаю ответ сервера (подтвержение соединения)
3. шлю куда хочу коннектиться (например www.google.com:80)
4. получаю ответ, что соединение установлено
5. шлю данные серверу:

GET / HTTP1.1+#13#10+
Host: www.google.com+#13#10#13#10

вот тут непонятки - очень редко когда приходит "200 OK", в основном приходит 400 ошибка, из 1к собранных socks5 примерно половина устанавливает соединение с сервером (остальные недоступны по таймауту), но не понятно как посылают данные ошибка 400 - очень часто приходит. 200 OK бывает очень редко - примерно 10 проксей из этих 1к.
Собственно, что делаю неправильно? почему получается ошибка 400? и почему все же иногда получаю таки 200 ОК? уже запарился голову ломать.

400 error код ошибки в протоколе HTTP, возникающей, когда запрос клиента не может быть понят

не правильно формируешь запрос

Сруктура GET запроса:

Код:

GET http://localhost/microtest.php HTTP/1.0
Accept: */*
Referer: http://localhost/1.php
Accept-Language: ru
Proxy-Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MRA 4.7 (build 01670); Crazy Browser 1.0.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: localhost
Cookie: PHPSESSID=rkp4kdodkh3190l8um92hl7oe1


rikko 13.02.2010 19:45

AlexTheC0d3r, все тоже самое, что твой запрос, что мой... только попробовал.
по-прежнему 98% ответов - 400 bad request
не в этом дело видать.

Chrome~ 13.02.2010 20:05

rikko, выложи часть кода.

rikko 13.02.2010 21:22

Код:

procedure TProxyCheckThread.Execute;
var
 sock:LongWord;
 block:u_long;
 SockAddrIn:TSockAddrIn;
 timeout:ttimeval;
 fds:TFDSet;
 rc,curr,len:integer;
 ws:TWSAData;
 send_buf, result:string;
 buf:array[0..4095] of char;

 socks5_req:record // привет
  ver:byte;
  nmet:byte;
  met:byte;
  end;
 socks5_resp:record //ответ на привет
  ver:byte;
  met:byte;
  end;
  socks5_req_TPC:record // куда подключаться
    ver:byte;
    cmd:byte;
    rsv:byte;
    atyp:byte;
    ip:u_long;
    port:u_short;
  end;
  socks5_resp_TPC:record // подключились
    ver:byte;
    cmd:byte;
    rsv:byte;
    atyp:byte;
    ip:u_long;
    port:u_short;
  end;
 

begin
 //приветствие
 socks5_req.ver:=5;
 socks5_req.nmet:=1;
 socks5_req.met:=0;
 WsaStartup($202,ws);
 //запрос соединения
 socks5_req_TPC.ver:=5;
 socks5_req_TPC.cmd:=1;
 socks5_req_TPC.rsv:=0;
 socks5_req_TPC.atyp:=1;
 socks5_req_TPC.ip:=inet_addr(Pansichar(GetipAddress(form1.edit2.Text)));
 socks5_req_TPC.port:=htons(strtoint('80'));


 block:=1;
 sock:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if sock=LongWord(-1) then exit;
 SockAddrIn.sin_family := AF_INET;
 SockAddrIn.sin_port := htons(strtoint(PROXY_PORT));
 SockAddrIn.sin_addr.s_addr := inet_addr(Pansichar(PROXY_IP));

 ioctlsocket(sock, FIONBIO, block); // переводим сокет в неблокируемый режим
 if connect(sock, SockAddrIn, SizeOf(SockAddrIn))=SOCKET_ERROR then // пытаемся подключиться
  begin
  if WSAGetLastError=WSAEWOULDBLOCK then // проверяем что сокет перешел в неблокируемый режим
    begin
      FD_ZERO(fds);
      FD_SET(sock,fds);
      timeout.tv_sec:=strtoint(form1.Edit1.Text); // наш таймаут
      timeout.tv_usec:=0;
      rc:=select(0, nil, @fds, nil, @timeout); // ожидаем
    end;
  end;
 block:=0;
 ioctlsocket(sock, FIONBIO, block); // переводим сокет обратно в блокируемый режим
if rc=0 then
 begin
  // сработал таймаут

  synchronize(showresultbad);
 end
else
 begin
  // удачно соединились
  // запрос для http
  send_buf:='GET http://'+form1.edit2.Text+'/ HTTP/1.1'#13#10+
              'Host: '+form1.edit2.Text+#13#10+
              'Accept: */*'+#13#10+
              'Proxy-Connection: Keep-Alive'+#13#10+
              'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MRA 4.7 (build 01670); Crazy Browser 1.0.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'#13#10#13#10;


    send(sock,socks5_req, 3,0); // шлем привет
          len := recv(sock, socks5_resp, 2, 0); // считали данные

          if len > 0 then // если есть чтото
          begin
            //смотрим результат
            if (socks5_resp.ver=5) and(socks5_resp.met=0) then //успех
              begin

                send(sock, socks5_req_TPC, 14,0); // запрос на соединение с http сервом
                len := recv(sock,  socks5_resp_TPC, 14, 0); // считали данные
                if len > 0 then
                  if socks5_resp_TPC.cmd=0 then //успех
                    begin

                        send(sock, send_buf[1], length(send_buf),0); // шлем наднные http серву через прокси
                            len := recv(sock,  buf, 4096, 0); // читаем ответ
                            if len > 0 then
                              begin
                                result := copy(buf, 0, len);
                                if pos('200 OK', result)<>0 then result:='GOOD';
                              end;
                    end;

              end;

          end;
    if result='GOOD' then synchronize(showresultgood);

 end;
  closesocket(sock);
  synchronize(dec_count);
end;

реализация для потоков.
реализация таймаута для прокси - взял у Слэша.
прокомментил отстальное.
повторюсь - иногда работает. 200 ok получаю. Очень часто - ошибка 400

Chrome~ 14.02.2010 00:02

У меня все работает стабильно, сервак возвращает код 200.
Я кое-что поменял.

Код:

socks5_req_TPC.ip:=inet_addr(Pansichar(GetipAddress(form1.edit2.Text)));
на
Код:

socks5_req_TPC.ip:=Integer(LookupName(form1.edit2.Text));
Код функции LookupName:
Код:

function LookupName(str: String): TInAddr;
var
  _hostEnt:PHostEnt;
  _inAddr:TInAddr;
begin
  if (str[1] in ['a'..'z']) or
      (str[2] in ['a'..'z']) then
  begin
    _hostEnt := getHostByName(pchar(str));
    FillChar(_inAddr, sizeOf(_inAddr), 0);
    if _hostEnt<>nil then
    begin
      with _hostEnt^, _inAddr do
      begin
        s_un_b.s_b1 := h_addr^[0];
        s_un_b.s_b2 := h_addr^[1];
        s_un_b.s_b3 := h_addr^[2];
        s_un_b.s_b4 := h_addr^[3];
      end;
    end;
  end
  else
    _inAddr.s_addr := inet_addr(pchar(str));
  Result:= _inAddr;
end;

Также вот эту строку:
Код:

SockAddrIn.sin_addr.s_addr := inet_addr(Pansichar(PROXY_IP));
изменил на:
Код:

SockAddrIn.sin_addr := LookupName(PROXY_IP);

rikko 14.02.2010 00:53

Chrome~, спасибо за совет, но у меня ничего не изменилось:
из 100 заведомо работающих проксей 18 отдают 200 OK, 82 прокси 400 Bad request, странно как то...

slesh 17.02.2010 21:04

2 rikko
socks5_req_TPC.port:=htons(strtoint('80')); - это жестоко.
лучше уж socks5_req_TPC.port := htons(80);
Вообще поподробнее попроверяй эти прокси.
Могут быть следующие ошибки
1) С коде проксей есть ошибка и запрос не полностью отправляется или хз что еще происходит. бывает всякое.
2) попробуй найти прокси которые дывают ошибку постоянно и подконнектится куданить туда где можно проверить всё. Если у тя есть внешний IP то на него на какойнить порт или проверить логи сервака. Как вариант пробовать запрос на echo сервис. тогда он ответит темже что ты ему послал и таким образом сможеш увидеть запрос который идет уже от прокси.

Также желательно проверять кол-во посланных данных с длинной буфера который ты посылал. просто хз почему но может быть такое что не до конца от тебя данные уходят.

Еще иногда бывает что траф компов както хитро фильтруется. Такое у сотовых операторов часто бывает
Это та часть по которой чтото может не пахать.

А вот часть по которой скорее всего не пашет
Код:

send_buf:='GET http://'+form1.edit2.Text+'/ HTTP/1.1'#13#10+
              'Host: '+form1.edit2.Text+#13#10+
              'Accept: */*'+#13#10+
              'Proxy-Connection: Keep-Alive'+#13#10+
              'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MRA 4.7 (build 01670); Crazy Browser 1.0.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'#13#10#13#10;

Ты же посылаешь запрос не на HTTP прокси.
Ты посылаешь на HTTP сервер через socks5 прокси
по этому он должен быть типа такой:
Код:

'GET / HTTP/1.0'#13#10+
'Host: site.com'#13#10#13#10

т.е. первый твой запрос был правильный, то там была ошибка на участке HTTP/1.0, а тот который тебе посоветывали - это запрос для HTTP прокси.

P.S. 2 AlexTheC0d3r если не знаешь, то лучше не пиши, а то путаешь человека.


Время: 17:49