|
Постоянный
Регистрация: 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->socket, pack("C3", 0x05, 0x01, 0x00));
$answer = "";
stream_set_timeout($this->socket, 0, $this->socket_timeout);
do {
$buf = @fread($this->socket, 1024);
$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->socket, pack("C5", 0x05, 0x01, 0x00, 0x03, strlen($host)) . $host .
pack("n", $port));
else
fwrite($this->socket, pack("C4Nn", 0x05, 0x01, 0x00, 0x01, ip2long(gethostbyname
($host)), $port));
$answer = "";
do {
$buf = @fread($this->socket, 1024);
$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..
Причина: Заголовок
|