Net-SC

 view release on metacpan or  search on metacpan

lib/Net/SC.pm  view on Meta::CPAN

	# ÄÅÓËÒÉÐÔÏÒ ÆÁÊÌÁ  × LOG_FH, ÎÏ ÔÏÇÄÁ ÎÁÄÏ ÞÔÏÂ LOG_FILE ÂÙÌ undef...
	#
	if ( $self->configure( 'SYSLOG' ) ) {
		if ( $^O =~ /[Ww]in32/ ) {
			require Win32::EventLog;

			$self->configure( 'LOG_FH' => Win32::EventLog->new( 'sc45', '' ) );

			unless ( defined $self->configure( 'LOG_FH' ) ) {
					$self->configure( SYSLOG => 0 );
					$self->log_error( "Cannot open EventLog:" . Win32::GetLastError() );
			}
		} else {
			require Sys::Syslog;
			import  Sys::Syslog qw(:DEFAULT setlogsock );

			if ( $^O ne 'solaris' && $^O ne 'freebsd' &&
					eval { &Sys::Syslog::_PATH_LOG() } ) {

				unless ( defined setlogsock( 'unix' ) ) {
					$self->configure( SYSLOG => 0 );
					$self->log_error("Can't `setlogsock' : $!");
				}
			}
			if ( not defined openlog( 'sc45', 'cons,pid', 'daemon') ) {
				$self->configure( SYSLOG => 0 );
				$self->log_error("Can't `openlog' : $!");
			}
		}
	} elsif ( defined $self->configure( 'LOG_FILE' ) ) {
		$key = gensym;
		$self->configure( LOG_FH => $key );
		if ( open ( $key , '>>' . $self->configure( 'LOG_FILE' ) ) ) {
			select((select($key), $| = 1)[0]);
		} else {
			$self->configure( LOG_FH => undef );
			$self->log_error("Can't open file " . $self->configure('LOG_FILE') ." : $!");
			ungensym $key;
		}
	}

	return $self;
}

#
# þÉÔÁÅÔ/ÕÓÔÁÎÁ×ÌÉ×ÁÅÔ ÐÅÒÅÍÅÎÎÙÅ ÉÚ 'ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÇÏ ÈÅÛÁ'
# ( ÔÏÔ ËÏÔÏÒÙÊ CFG_... )
# åÓÌÉ ÚÁÄÁÎÏ 2 ÁÒÇÕÍÅÎÔÁ ÔÏ ÕÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ ÐÅÒÅÍÅÎÎÁÑ
# Ó ÉÍÅÎÅÍ `ÐÅÒ×ÙÊ ÁÒÇÕÍÅÎÔ' × ÚÎÁÞÅÎÉÅ `×ÔÏÒÏÊ ÁÒÇÕÍÅÎÔ',
# É ×ÏÚ×ÒÁÝÁÅÔ ÄÁÎÎÏÅ ÚÎÁÞÅÎÉÅ.
# åÓÌÉ ÚÁÄÁÎ ÏÄÉÎ ÁÒÇÕÍÅÎÔ ÔÏ ×ÏÚ×ÒÁÝÁÅÔ ÐÅÒÅÍÅÎÎÕÀ Ó
# ÉÍÅÎÅÍ `ÐÅÒ×ÙÊ ÁÒÇÕÍÅÎÔ'...
#
sub configure {
	my ( $self, $section, $var ) = @_;
	local $_;

	unless ( exists $self->{ 'CFG_' . uc($section) } ) {
		$self->log_error("Use unknown configuration variable : `$section'");
		return undef;
	} elsif ( uc($section) eq 'CHAIN_DATA' and (caller)[0] ne __PACKAGE__ ) {
		#
		# íÁÌÅÎØËÁÑ ËÕÞËÁ ÓÏÌÏÍËÉ, ÏÔ ÉÚÍÅÎÅÎÉÑ ÄÁÎÎÙÈ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÇÏ ÆÁÊÌÁ...
		#
		return $self->{ 'CFG_' . uc($section) };
	} else {
		if ( scalar @_ > 2 ) {
			$self->{ 'CFG_' . uc($section) } = $var;
		}
		return $self->{ 'CFG_' . uc($section) };
	}
}

#
# óÏÅÄÉÎÅÎÉÅ Ó ÕÄÁÌÅÎÎÏÊ ÍÁÛÉÎÏÊ ÞÅÒÅÚ socks ÃÅÐØ.
#
# îÕ ÜÔÏ ×ÒÏÄÅ ËÁË ÐÒÏÓÔÏ ÏÂÅÒÔËÁ ÄÌÑ create_chain,
# ÐÌÀÓ Á×ÔÏÍÁÔÉÞÅÓËÏÅ ÞÔÅÎÉÅ ËÏÎÆÉÇÏ×.
#
# ÷ÏÚ×ÒÁÝÁÅÔ SOCKS_OK ÅÓÌÉ ×ÓÅ OK
#
sub connect {
	my ( $self, $peer_host, $peer_port ) = @_;
	my $rc;
	local $_;

	unless ( defined $self->configure( 'CHAIN_DATA' ) ) {
		unless ( ( $rc = $self->read_chain_data ) == SOCKS_OKAY ) {
			return $rc;
		}
		if ( $self->configure( 'AUTO_SAVE' ) ) {
			$self->restore_cfg_data;
		}
	}

	$rc = $self->create_chain( $peer_host, $peer_port, 1 );

	if ( $self->configure( 'AUTO_SAVE' ) ) {
		$self->dump_cfg_data;
	}

	return $rc;
}

#
# õÓÔÁÎÏ×ËÁ Ó×ÑÚÉ ÄÌÑ ÐÒÉÎÑÔÉÑ ÓÏÅÄÉÎÅÎÉÊ ÞÅÒÅÚ socks ÃÅÐØ.
#
# îÕ ÜÔÏ ×ÒÏÄÅ ËÁË ÐÒÏÓÔÏ ÏÂÅÒÔËÁ ÄÌÑ create_chain,
# ÐÌÀÓ Á×ÔÏÍÁÔÉÞÅÓËÏÅ ÞÔÅÎÉÅ ËÏÎÆÉÇÏ×.
#
# ÷ÏÚ×ÒÁÝÁÅÔ SOCKS_OK ÅÓÌÉ ×ÓÅ OK
#
sub bind {
	my ( $self, $peer_host, $peer_port ) = @_;
	my $rc;
	local $_;

	unless ( defined $self->configure( 'CHAIN_DATA' ) ) {
		unless ( ( $rc = $self->read_chain_data ) == SOCKS_OKAY ) {
			return $rc;
		}

lib/Net/SC.pm  view on Meta::CPAN


			$self->mark_proxy( $self->{__last_socks}, $rc );

			unless ( $rc == SOCKS_OKAY ) {
				if ( $self->configure( 'DEBUG' ) & 0x01 ) {
					$self->debug( "Socks error[$rc]: " . $self->log_str( $hosts_id[$host_ind+1] ) );
				}
				if ( $self->configure( 'DEBUG' ) & 0x08 ) {
					$self->debug( '            [ ' . ( socks_error($rc) ) . ' ]' );
				}
				splice( @hosts_id, $host_ind+1, 1);
				redo CHAIN;
			}
		}
	}

	if ( $host_ind < $self->configure( 'CHAIN_LEN' ) - 1 ) {
		$self->log_error("Can't create socks chain, many servers not response...");
		return SOCKS_FAILED;
	}

	#
	# Create connectino to destination addr/port
	#
	if ( $self->socks_param( 'protocol_version' ) == 5 ) {
		$rc = $self->request_socks5( $type, $peer_host, $peer_port );
	} elsif ( $self->socks_param( 'protocol_version' ) == 0 ) {
		$rc = $self->request_http( $type, $peer_host, $peer_port  );
	} else {
		$rc = $self->request_socks4( $type, $peer_host, $peer_port  );
	}

	$self->mark_proxy( $self->{__last_socks}, $rc );

	return $rc;
}

#
# ðÒÏÃÅÄÕÒÁ ÂÌÏËÉÒÏ×ËÉ ÆÁÊÌÏ×, Ó ÕÞÅÔÏÍ ÐÒÏ×ÅÒËÉ ÎÁ ×ÏÚÍÏÖÎÏÓÔÉ ÓÉÓÔÅÍÙ...
#
sub my_flock {
	my ( $fh, $mode ) = @_;

	return 1 unless defined $Config::Config{d_flock};

	flock ( $fh, $mode );
}

#
# éÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÏÔÌÁÄËÉ - ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ SYSLOG'Á ÓÏÏÂÝÅÎÉÑ ÐÉÛÕÔÓÑ
# × `debug', ÅÓÌÉ syslog ÎÅ ÐÏÌØÚÕÅÔÓÑ ÔÏ ×ÙÚÙ×ÁÅÔÓÑ log_error...
#
sub debug {
	my $self = shift;

	#
	# syslogd
	#
	if ( ref $self and $self->configure( 'SYSLOG' ) and $^O !~ /[Ww]in32/ ) {
		foreach ( @_ ) {
			syslog( 'debug', '%s [ %d ]', $_, (caller)[-1] ) unless /^\s*$/;
		}
		return 1;
	}
	#
	# ÷ÓÅ ÏÓÔÁÌØÎÏÅ
	#
	return log_error( $self, @_);
}

#
# ðÉÛÅÔ ÓÏÏÂÝÅÎÉÑ Ï ÏÛÉÂËÁÈ × log ÆÁÊÌ ÉÌÉ ÐÅÒÅÄÁÅÔ syslogd.
# íÏÖÎÏ ÂÙÌÏ ËÏÎÅÞÎÏ Carp.pm ÐÏÌØÚÏ×ÁÔØ, ÎÏ ÐÒÉ×ÙÞËÁ...
#

sub log_error {
	my $self = shift;
	my $sym;
	local $_;

	if ( ref $self and $self->configure( 'SYSLOG' ) and $^O !~ /[Ww]in32/ ) {
		#
		# syslogd
		#
		foreach ( @_ ) {
			syslog( 'warning', '%s [ %d ]', $_, (caller)[-1] ) unless /^\s*$/;
		}
	} elsif (	ref $self and
				$self->configure( 'SYSLOG' ) and
				defined $self->configure( 'LOG_FH' ) ) {
		#
		# eventlog
		#
		$self->configure('LOG_FH')->Report( {
				Category	=> 20,
				EventType	=> Win32::EventLog::EVENTLOG_INFORMATION_TYPE(),
				Strings		=> join( "\n", '', @_ ),
				Data		=> '',
				EventID		=> 0
		} );
	} else {
		#
		# write co STDERR
		#
		unless ( ref $self ) {
			unshift @_, $self;
			$sym = \*STDERR;
		} elsif ( not defined ( $sym = $self->configure( 'LOG_FH' ) ) ) {
				$sym = \*STDERR;
		}
		my_flock ( $sym, LOCK_EX );
		foreach ( @_ ) {
			printf $sym "%2.2d/%2.2d %2.2d:%2.2d:%2.2d [ %5.5d : %d ] : %s\n",(localtime(time))[3,4,2,1,0], $$, (caller)[-1], $_ unless /^\s*$/;
		}
		my_flock ( $sym, LOCK_UN );
	}

	return 1;
}

#
# ÷ÏÚ×ÒÁÝÁÅÔ ÌÏÇ ÓÔÒÏËÕ Ï ÓÏÅÄÉÎÅÎÉÉ id...
#
sub log_str {
	my ( $self, $id ) = @_;
	my $str;
	local $_;

	$str = '';

	foreach ( @{$self->configure('LOG_SOCKS_FIELD')} ) {
		if ( defined $self->socks_param( $_, undef, $id ) ) {
			$str .= ' : ' . $self->socks_param( $_, undef, $id );
		} else {
			$str .= ' : ';
		}
	}

	return substr $str, 3;
}

#
# ðÒÏÉÚ×ÏÄÉÔ ËÏÎÎÅËÔ × `ÏÔËÒÙÔÕÀ' Ë ÐÅÒ×ÏÍÕ socks ÓÅÒ×ÅÒÕ.
#
# åÓÌÉ ×ÓÅ Ok ×ÏÚ×ÒÁÝÁÅÔ SOCKS_OKAY
#
sub first_connect {
	my $self = shift;
	local $_;

	$self->{sock_h} = new IO::Socket::INET (
			PeerAddr	=> $self->socks_param( 'addr' ),
			PeerPort	=> $self->socks_param( 'port' ),
			Timeout		=> $self->configure( 'TimeOut' ),
			Proto		=> 'tcp'
		);

	unless ( defined $self->sh ) {
		$self->log_error( $@, "Can't create network socket... : $!" );
		return SOCKS_FAILED;
	}

	binmode $self->sh;

	$self->sh->autoflush(1);

	return SOCKS_OKAY;
}

#
# þÉÔÁÅÔ ÄÁÎÎÙÅ ÉÚ ÓÏËÅÔÁ $fh1. $fh2 ÍÏÖÅÔ ÂÙÔØ ËÁË ÓÓÙÌËÏÊ ÎÁ ÓÏËÅÔ
# ÔÁË É ÓÓÙÌËÏÊ ÎÁ ÓËÁÌÑÒ, ÄÌÑ ÐÅÒ×ÏÇÏ ÓÌÕÞÁÑ ÄÏÌÖÎÏ ÂÙÔØ ÏÐÒÅÄÅÌÅÎÏ
# ÚÎÁÞÅÎÉÅ $cnt. åÓÌÉ $fh2 ÓÓÙÌËÁ ÎÁ ÓÏËÅÔ ( ÆÁÊÌÏ×ÙÊ ÄÅÓËÒÉÐÔÏÒ )



( run in 1.062 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )