• XSS.stack #1 – первый литературный журнал от юзеров форума

объектный модуль для организации сервера распредел

KSURi

RAID-массив
Пользователь
Регистрация
28.05.2006
Сообщения
72
Реакции
1
Откопал сорец месячной давности...)
Полноценный объектный модуль для организации сервера распределенных вычислений (если точнее брут мд5). Я тут подумал... Через пару дней напишу Pod доку для него и скину.
Код в принципе не сложный, думаю разберетесь.
Ежели какие вопросы - пишите тут.
Код:
package Distributed;

use strict;
use vars qw($VERSION @ISA @EXPORT_OK);
use IO::Socket;
use threads;

$VERSION="0.01";
@ISA=qw(IO::Socket threads);
@EXPORT_OK=qw(host port logFile clientsFile taskFile foundFile maxClients DEBUG);

sub new
{
    my($class,%args)=@_;
    my $self={%args};
    if(!exists($self->{host}))        { $self->{host}="127.0.0.1"          }
    if(!exists($self->{port}))        { $self->{port}=31337                }
    if(!exists($self->{logFile}))     { $self->{logFile}="server.log"      }
    if(!exists($self->{clientsFile})) { $self->{clientsFile}="clients.dat" }
    if(!exists($self->{taskFile}))    { $self->{taskFile}="clients.dat"    }
    if(!exists($self->{foundFile}))   { $self->{foundFile}="found.dat"     }
    if(!exists($self->{maxClients}))  { $self->{maxClients}=10             }
    if(!exists($self->{DEBUG}))       { $self->{DEBUG}=0                   }
    return bless($self,ref($class)||$class);
}

sub startServer
{
    my $self=shift;
    print "Debug: starting server\n" if $self->{DEBUG};
    my $i=0;
    my $socket=IO::Socket::INET->new(LocalAddr=>scalar($self->{host}),
                                     LocalPort=>int($self->{port}),
                                     Listen=>int($self->{maxClients}),
                                     Proto=>"tcp",
                                     Type=>SOCK_STREAM,
                                     Blocking=>0)||exit print __FILE__.": ".__LINE__.": can not create socket: ".$!."\n";
    while(1)
    {
        next unless(my $newConnection=$socket->accept());
        my $clData=threads->create(\&processClient,$i,$newConnection)->detach();
        if($clData eq "processed") { $self->logAction($newConnection->peer()." was processed\n"); }
        elsif($clData eq "found") { $self->logAction($newConnection->peer()." found the password for task=".$i++."\n"); }
        else { $self->logAction($newConnection->peer()." was failed to process\n"); }
    }
}

sub logAction
{
    my($self,$action)=@_;
    print "Debug: logging\n" if $self->{DEBUG};
    open(LOG,">>$self->{logFile}")||exit print __FILE__.": ".__LINE__.": can not open logfile: ".$!."\n";
    print LOG localtime()." - ".$action."\n";
    close LOG;
}

sub processClient
{
    my($self,$clCtr,$conn)=@_;
    print "Debug: client connected\n" if $self->{DEBUG};
    my($response,@splitResponse);
    my @idArr=split('\.',$conn->peer());
    my $id=$idArr[2].$idArr[3];
    undef @idArr;
    $conn->recv($response,128);
    @splitResponse=split(':',$response);
    if($splitResponse[0] eq "COMMAND"&&$splitResponse[1] eq "OLD")
    {
        if($self->verifyClient($id) eq "success")
        {
            $conn->send("STATUS:OK",0,0);
            $conn->recv($response,128);
            @splitResponse=(':',$response);
            if($splitResponse[0] eq "TASK"&&$splitResponse[1] eq "GET")
            {
                my @task=getTask($clCtr);
                foreach(@task) { $conn->send($_,0,0); sleep(1); }
                $conn->recv($response,128);
                if($response eq "STATUS:OK")
                {
                    close $conn&&undef $conn;
                    return "processed";
                }
                else { return "failed"; }
            }
            elsif($splitResponse[0] eq "STATUS")
            {
                if($splitResponse[1] eq "FOUND")
                {
                    open(FOUNDDB,">>$self->{foundFile}")||exit print __FILE__.": ".__LINE__.": can not open passwords file: ".$!."\n";
                    print FOUNDDB "Hash:".$splitResponse[2]." Password: ".$splitResponse[3]."\n";
                    close FOUNDDB;
                    close $conn&&undef $conn;
                    open(TASKDB,">>$self->{taskFile}")||exit print __FILE__.": ".__LINE__.": can not open tasks database: ".$!."\n";
                    while(<TASKDB>)
                    {
                        if(/$splitResponse[2]/) { next; }
                        else { print TASKDB $_; }
                    }
                    close TASKDB;
                    return "found";
                }
                elsif($splitResponse[1] eq "NOTFOUND")
                {
                    $conn->send("STATUS:OK");
                    $conn->recv($response,128);
                    if($response eq "TASK:GET")
                    {
                        my @task=getTask($clCtr);
                        foreach(@task) { $conn->send($_,0,0); sleep(1); }
                        $conn->recv($response,128);
                        if($response eq "STATUS:OK")
                        {
                            close $conn&&undef $conn;
                            return "processed";
                        }
                        else
                        {
                            close $conn&&undef $conn;
                            return "failed";
                        }
                    }
                    else
                    {
                        close $conn&&undef $conn;
                        return "failed";
                    }
                }
                else
                {
                    close $conn&&undef $conn;
                    return "failed";
                }
            }
            else
            {
                close $conn&&undef $conn;
                return "failed";
            }
        }
        else
        {
            close $conn&&undef $conn;
            return "failed";
        }
    }
}

sub regNewClient
{
    my($self,$id)=@_;
    print "Debug: processing *new* client\n" if $self->{DEBUG};
    open(CLBD,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
    print CLBD $id."\n";
    close CLBD;
    print "Debug: *new* client have been added to database with id=".$id."\n";
}

sub verifyClient
{
    my($self,$id)=@_;
    print "Debug: verifieng client with id=".$id."\n" if $self->{DEBUG};
    open(CLIENTSDB,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
    while(<CLIENTSDB>)
    {
        chomp($_);
        close CLIENTSDB&&return "success" if($_ eq $id);
    }
    close CLIENTSDB&&return "failed";
}

sub getTask
{
    my($self,$taskId)=@_;
    print "Debug: getting a piece of task with id=".$taskId."\n" if $self->{DEBUG};
    my($taskReady,$currClientsNum)=0;
    my($id,$hash,$length,$charset,$range,$allVariants) ;
    open(TASKDB,$self->{taskFile})||exit print __FILE__.": ".__LINE__.": can not open tasks database: ".$!."\n";
    open(CLIENTSDB,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
    $currClientsNum++ while(<CLIENTSDB>);
    close CLIENTSDB;
    while(<TASKDB>)
    {
        if(/^$taskId;/)
        {
            chomp($_);
            ($id,$hash,$length,$charset)=split(';',$_);
            for(my $i=1;$i<=$length;$i++) { $allVariants.=$i**length($charset) }
            $range=int($allVariants/$currClientsNum);
            $taskReady=1;
        }
    }
    if($taskReady==0)
    {
        print __FILE__.": ".__LINE__.": no task with id=".$taskId."\n";
        return "failed";
    }
    close TASKDB;
    return my @retData=("TASK:HASH:".$hash,
                        "TASK:LENGTH:".$length,
                        "TASK:CHARSET:".$charset,
                        "TASK:RANGE:".$range);
}

1; # Единичка! Я закончил писать;)

# Distributed.pm
# (C)oded by .:[KSURi]:.
# http://cup.su/
 
Наконец закончил новую версию модуля.
Теперь есть документация и тд)
Добавил пару новых методов.

Архив состоит из:
Distributed.pm - perl source, сам модуль
Distributed.html - html дока
Client.pl - perl source, пример простейшего клиента (без кряка)
db.sql - sql source, создает нужные таблицы в базе

Текущая версия 0.03.
Надеюсь комунить пригодится.
http://www.megaupload.com/?d=NOZ8IT2W
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх