Показать сообщение отдельно

Работ через соксы
  #8  
Старый 25.08.2008, 16:20
Doom123
Постоянный
Регистрация: 11.11.2006
Сообщений: 834
Провел на форуме:
3941248

Репутация: 668


По умолчанию Работ через соксы

Работ через socks

PHP код:
<?
/**
 * Class for work using SOCKS5 protocol.
 * Copyright by Elw00d
 * В данный момент поддерживаются лишь исходящие TCP-соединения с socks5-сервером, не требующим авторизации
 */
class socks5
{
    var 
$ip;
    var 
$port;
    var 
$socket;
    var 
$socket_timeout;
    var 
$connected// есть ли установленное соединение ЧЕРЕЗ сокс с удаленным хостом

    // конструктор — инициализирует переменные класса, но никуда не подключается
    
function socks5($ip$port$timeout 3000)
    {
        
$this->socket 0;
        
$this->socket_timeout $timeout;
        
$this->ip $ip;
        
$this->port $port;
        
$this->connected false;
        return 
true;
    }

    
// подключение к сокс-серверу (только socks5)
    // авторизация user/pass не поддерживается
    // timeout — в миллисекундах
    // возвращает true/false в зависимости от успеха операции
    
function socks5_init()
    {
        if (
$this->socket = @pfsockopen($this->ip$this->port$errno$errstr$this->
            
socket_timeout 1000)) {
            
fwrite($this->socketpack("C3"0x050x010x00));
            
$answer "";
            
stream_set_timeout($this->socket0$this->socket_timeout);
            do {
                
$buf = @fread($this->socket1024);
                
$socket_status stream_get_meta_data($this->socket);
                if (
$buf && !$socket_status['timed_out'])
                    
$answer .= $buf;
                if (
$socket_status['eof']) {
                    
$this->socket 0;
                    return 
false// сервер закрыл коннект
                
}
            } while (
strlen($answer) < 2);
            
$response = @unpack("Cver/Cmethod"$answer);
            if (
$response["ver"] == 0x05 and $response["method"] == 0x00)
                return 
true;
            
fclose($this->socket);
            
$this->socket 0;
        }
        return 
false;
    }

    
// установка TCP-соединения с хостом через сокс-сервер
    // после успешного соединения флаг $this->connected устанавливается в true
    // возвращает true/false
    
function socks5_connect($host$port)
    {
        if (
$this->socket) {
            if (
ip2long($host) == -1)
                
fwrite($this->socketpack("C5"0x050x010x000x03strlen($host)) . $host .
                    
pack("n"$port));
            else
                
fwrite($this->socketpack("C4Nn"0x050x010x000x01ip2long(gethostbyname
                    
($host)), $port));
            
$answer "";
            do {
                
$buf = @fread($this->socket1024);
                
$socket_status stream_get_meta_data($this->socket);
                if (
$buf && !$socket_status['timed_out'])
                    
$answer .= $buf;
                if (
$socket_status['eof']) {
                    
$this->socket 0;
                    return 
false// сервер закрыл коннект
                
}
            } while (
strlen($answer) < 4);
            
$response = @unpack("Cversion/Cresult/Creg/Ctype/Lip/Sport"$answer);
            if (
$response["version"] == 0x05 and $response["result"] == 0x00) {
                
$this->connected true;
                return 
true;
            }
        }
        return 
false;
    }

    
// позволяет получить дескриптор сокета соединения с сокс-сервером
    // после того, как соединение через сокс установлено, можно напрямую отправлять/принимать данные из этого сокета,
    // общаясь таким образом с удаленным хостом. Все выглядит так, как будто сокет соединен напрямую с целевым хостом.
    // Совет: пользоваться этой функцией с осторожностью, не вызывать напрямую fclose(), юзать метод socks5_closeconnection()
    // Вопрос: зачем эта функция, если она нарушает инкапсуляцию класса?
    // Ответ: да, это пренебрежение к канонам ООП, но зато делает удобной доработку существующих скриптов в сторону
    // соксификации. Вместо того, чтобы отлаживать ещё один слой ввода-вывода, легче дописать к скрипту процедурку
    // инициализации соединения через сокс + добавочную обработку ошибок (специально для соксов), а потом просто получать
    // дескриптор сокета и не трогать исходные вызовы fread(), fwrite() или stream_set_timeout(). Если же необходимо
    // закрыть соединение, достаточно просто вместо fclose() вызвать socks5_closeconnection(). В том случае, если сокс
    // отваливается по таймауту, вообще не надо ничего менять, и разрыв коннекта интерпретируется скриптом по-старому.
    
function socks5_getsocket()
    {
        return 
$this->socket;
    }

    function 
socks5_closeconnection()
    {
        
//if ($this->socket)
        
@fclose($this->socket);
        
$this->connected false;
        
$this->socket 0;
    }
}
?>
Использование

PHP код:
<?php
set_time_limit
(0);

    include(
"socks.class.php");
    
    
$server_name "whatismyip.com";
    
$server_port 80
    
$socks = new socks5("127.0.0.1"33142);
    
$socks->socks5_init();
    if (
$socks->socks5_connect($server_name$server_port)) {
        
        
// формируем запрос ,который будет отправлен, через сокс, серверу
        
$head "GET / HTTP/1.0\r\n";
        
$head .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.52\r\n";
        
$head .= "Host: www.whatismyip.com\r\n";
        
$head .= "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n";
        
$head .= "Accept-Language: ru,en;q=0.9\r\n";
        
$head .= "Accept-Charset: windows-1252, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n";
        
$head .= "Proxy-Connection: close\r\n\r\n";
        
        
fwrite($socks->socks5_getsocket(),$head);
        
// считываем ответ HTTP-сервера через SOCKS-сервер до конца =)
        
while(!feof($socks->socks5_getsocket()))
        {
        
$l=fread($socks->socks5_getsocket(),1024);
        echo 
$l;
        }
        
    }
?>

Последний раз редактировалось Doom123; 25.08.2008 в 16:21.. Причина: Заголовок
 
Ответить с цитированием