<s> __author__ = '<STR_LIT>' <EOL> from log import Logger <EOL> from protos . message import Command , PING , STUN , STORE , INV , VALUES , GET_LISTINGS , FOLLOW , UNFOLLOW <EOL> from twisted . internet import reactor , task <EOL> RECONNECTIONS = <NUM_LIT:100> <EOL> MALFORMATED = <NUM_LIT> <EOL> SCORES = { <EOL> PING : <NUM_LIT:0> , <EOL> STUN : <NUM_LIT:0> , <EOL> STORE : <NUM_LIT:0> , <EOL> INV : <NUM_LIT:0> , <EOL> VALUES : <NUM_LIT:0> , <EOL> GET_LISTINGS : <NUM_LIT:0> , <EOL> FOLLOW : <NUM_LIT:0> , <EOL> UNFOLLOW : <NUM_LIT:0> , <EOL> RECONNECTIONS : <NUM_LIT:0> , <EOL> MALFORMATED : <NUM_LIT:0> <EOL> } <EOL> class BanScore ( object ) : <EOL> def __init__ ( self , multiplexer , ban_time = <NUM_LIT> ) : <EOL> self . multiplexer = multiplexer <EOL> self . ban_time = ban_time <EOL> self . peers = { } <EOL> self . scoring_loop = task . LoopingCall ( self . adjust_scores ) <EOL> self . log = Logger ( system = self ) <EOL> def process_message ( self , peer , message ) : <EOL> if peer : <EOL> return <EOL> if peer [ <NUM_LIT:0> ] not in self . peers : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] = SCORES . copy ( ) <EOL> try : <EOL> if message == <NUM_LIT:100> : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ RECONNECTIONS ] += <NUM_LIT:1> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ RECONNECTIONS ] > <NUM_LIT:10> : <EOL> self . ban ( peer , RECONNECTIONS ) <EOL> return <EOL> elif message == <NUM_LIT> : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ MALFORMATED ] += <NUM_LIT:1> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ MALFORMATED ] > <NUM_LIT:10> : <EOL> self . ban ( peer , MALFORMATED ) <EOL> return <EOL> if message . command == PING : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ PING ] += <NUM_LIT:0.5> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ PING ] > <NUM_LIT:10> : <EOL> self . ban ( peer , PING ) <EOL> elif message . command == STUN : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ STUN ] += <NUM_LIT:1> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ STUN ] > <NUM_LIT:1> : <EOL> self . ban ( peer , STUN ) <EOL> elif message . command == STORE : <EOL> args = tuple ( message . arguments ) <EOL> for arg in args : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ STORE ] += len ( arg ) <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ STORE ] > <NUM_LIT> : <EOL> self . ban ( peer , STORE ) <EOL> elif message . command == INV : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ INV ] += <NUM_LIT:30> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ INV ] > <NUM_LIT> : <EOL> self . ban ( peer , INV ) <EOL> elif message . command == VALUES : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ VALUES ] += <NUM_LIT:30> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ VALUES ] > <NUM_LIT> : <EOL> self . ban ( peer , VALUES ) <EOL> elif message . command == GET_LISTINGS : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ GET_LISTINGS ] += <NUM_LIT:5> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ GET_LISTINGS ] > <NUM_LIT> : <EOL> self . ban ( peer , GET_LISTINGS ) <EOL> elif message . command == FOLLOW : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ FOLLOW ] += <NUM_LIT:1> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ FOLLOW ] > <NUM_LIT:3> : <EOL> self . ban ( peer , FOLLOW ) <EOL> elif message . command == UNFOLLOW : <EOL> self . peers [ peer [ <NUM_LIT:0> ] ] [ UNFOLLOW ] += <NUM_LIT:1> <EOL> if self . peers [ peer [ <NUM_LIT:0> ] ] [ UNFOLLOW ] > <NUM_LIT:3> : <EOL> self . ban ( peer , UNFOLLOW ) <EOL> except Exception : <EOL> self . log . warning ( "<STR_LIT>" ) <EOL> def ban ( self , peer , message_type ) : <EOL> if message_type == <NUM_LIT:100> : <EOL> reason = "<STR_LIT>" <EOL> elif message_type == <NUM_LIT> : <EOL> reason = "<STR_LIT>" <EOL> else : <EOL> reason = Command . Name ( message_type ) <EOL> self . log . warning ( "<STR_LIT>" % <EOL> ( peer [ <NUM_LIT:0> ] , reason ) ) <EOL> self . multiplexer . ban_ip ( peer [ <NUM_LIT:0> ] ) <EOL> if peer in self . multiplexer : <EOL> self . multiplexer [ peer ] . shutdown ( ) <EOL> reactor . callLater ( self . ban_time , self . multiplexer . remove_ip_ban , peer [ <NUM_LIT:0> ] ) <EOL> def adjust_scores ( self ) : <EOL> for peer in self . peers . keys ( ) : <EOL> remove = True <EOL> for k , v in self . peers [ peer ] . items ( ) : <EOL> if v > <NUM_LIT:0> : <EOL> remove = False <EOL> if k == STORE : <EOL> self . peers [ peer ] [ k ] = v - <NUM_LIT> <EOL> else : <EOL> self . peers [ peer ] [ k ] = v - <NUM_LIT:1> <EOL> if remove : <EOL> del self . peers [ peer ] </s>
