Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
IO::Socket::Socks(3)  User Contributed Perl Documentation IO::Socket::Socks(3)

NAME
       IO::Socket::Socks - Provides a way to create socks client or server
       both 4 and 5 version.

SYNOPSIS
   Client
	 use IO::Socket::Socks;

	 my $socks_client = IO::Socket::Socks->new(
	   ProxyAddr   => "proxy host",
	   ProxyPort   => "proxy port",
	   ConnectAddr => "remote host",
	   ConnectPort => "remote port",
	 ) or die $SOCKS_ERROR;

	 print $socks_client "foo\n";
	 $socks_client->close();

   Server
	 use IO::Socket::Socks ':constants';

	 my $socks_server = IO::Socket::Socks->new(
	   ProxyAddr   => "localhost",
	   ProxyPort   => 8000,
	   Listen      => 1,
	   UserAuth    => \&auth,
	   RequireAuth => 1
	 ) or die $SOCKS_ERROR;

	 while(1) {
	   my $client =	$socks_server->accept();

	   unless ($client) {
	     print "ERROR: $SOCKS_ERROR\n";
	     next;
	   }

	   my $command = $client->command();
	   if ($command->[0] ==	CMD_CONNECT) {
	      #	Handle the CONNECT
	      $client->command_reply(REPLY_SUCCESS, addr, port);
	   }

	   ...
	   #read from the client and send to the CONNECT address
	   ...

	   $client->close();
	 }

	 sub auth {
	   my ($user, $pass) = @_;

	   return 1 if $user eq	"foo" && $pass eq "bar";
	   return 0;
	 }

DESCRIPTION
       "IO::Socket::Socks" connects to a SOCKS proxy, tells it to open a
       connection to a remote host/port	when the object	is created.  The
       object you receive can be used directly as a socket (with "IO::Socket"
       interface) for sending and receiving data from the remote host. In
       addition	to create socks	client this module could be used to create
       socks server. See examples below.

EXAMPLES
       For complete examples of	socks 4/5 client and server see	`examples'
       subdirectory in the distribution.

METHODS
   Socks Client
       new( %cfg )

       new_from_socket($socket,	%cfg)

       new_from_fd($socket, %cfg)

       Creates a new IO::Socket::Socks client object.  new_from_socket() is
       the same	as new(), but allows one to create object from an existing and
       not connected socket (new_from_fd is new_from_socket alias). To make
       IO::Socket::Socks object	from connected socket see "start_SOCKS"

       Both takes the following	config hash:

	 SocksVersion => 4 or 5. Default is 5

	 Timeout => connect/accept timeout

	 Blocking => Since IO::Socket::Socks version 0.5 you can perform non-blocking connect/bind by
		     passing false value for this option. Default is true - blocking. See ready()
		     below for more details.

	 SocksResolve => resolve host name to ip by proxy server or
			 not (will resolve by client). This
			 overrides value of $SOCKS4_RESOLVE or $SOCKS5_RESOLVE
			 variable. Boolean.

	 SocksDebug => This will cause all of the SOCKS	traffic	to
		       be presented on the command line	in a form
		       similar to the tables in	the RFCs. This overrides value
		       of $SOCKS_DEBUG variable. Boolean.

	 ProxyAddr => Hostname of the proxy

	 ProxyPort => Port of the proxy

	 ConnectAddr =>	Hostname of the	remote machine

	 ConnectPort =>	Port of	the remote machine

	 BindAddr => Hostname of the remote machine which will
		     connect to	the proxy server after bind request

	 BindPort => Port of the remote	machine	which will
		     connect to	the proxy server after bind request

	 UdpAddr => Expected address where datagrams will be sent. Fill	it with	address
		    of all zeros if address is not known at this moment.
		    Proxy server may use this information to limit access to the association.

	 UdpPort => Expected port where	datagrams will be sent.	Use zero port
		    if port is not known at this moment. Proxy server may use this
		    information	to limit access	to the association.

	 AuthType => What kind of authentication to support:
		     none	- no authentication (default)
		     userpass  - Username/Password. For	socks5
		     proxy only.

	 RequireAuth =>	Do not send ANON as a valid auth mechanism.
			For socks5 proxy only

	 Username => For socks5	if AuthType is set to userpass,	then
		     you must provide a	username. For socks4 proxy with
		     this option you can specify userid.

	 Password => If	AuthType is set	to userpass, then you must
		     provide a password. For socks5 proxy only.

       The following options should be specified:

	 (ProxyAddr and	ProxyPort)
	 (ConnectAddr and ConnectPort) or (BindAddr and	BindPort) or (UdpAddr and UdpPort)

       Other options are facultative.

	start_SOCKS($socket, %cfg)

       This is a class method to start socks handshake on already connected
       socket. This will bless passed $socket to IO::Socket::Socks class. %cfg
       is like hash in the constructor.	 Only options listed below makes
       sence:

	 Timeout
	 ConnectAddr
	 ConnectPort
	 BindAddr
	 BindPort
	 UdpAddr
	 UdpPort
	 SocksVersion
	 SocksDebug
	 SocksResolve
	 AuthType
	 RequireAuth
	 Username
	 Password
	 AuthMethods

       On success this method will return same $socket,	but as
       IO::Socket::Socks object. On failure it will return undef (but socket
       will be still blessed to	IO::Socket::Socks class). See example:

	 use IO::Socket;
	 use IO::Socket::Socks;

	 my $sock = IO::Socket::INET->new("$proxy_host:$proxy_port") or	die $@;
	 $sock = IO::Socket::Socks->start_SOCKS($sock, ConnectAddr => "google.com", ConnectPort	=> 80) or die $SOCKS_ERROR;

	version( )

       Returns socks version for this socket

	ready( )

       Returns true when socket	becomes	ready to transfer data (socks
       handshake done),	false otherwise. This is useful	for non-blocking
       connect/bind. When this method returns false value you can determine
       what socks handshake need for with $SOCKS_ERROR variable. It may	need
       for read, then $SOCKS_ERROR will	be SOCKS_WANT_READ or need for write,
       then it will be SOCKS_WANT_WRITE.

       Example:

	   use IO::Socket::Socks;
	   use IO::Select;

	   my $sock = IO::Socket::Socks->new(
	       ProxyAddr => 'localhost', ProxyPort => 1080, ConnectAddr	=> 'mail.com', ConnectPort => 80, Blocking => 0
	   ) or	die $SOCKS_ERROR;

	   my $sel = IO::Select->new($sock);
	   until ($sock->ready)	{
	       if ($SOCKS_ERROR	== SOCKS_WANT_READ) {
		   $sel->can_read();
	       }
	       elsif ($SOCKS_ERROR == SOCKS_WANT_WRITE)	{
		   $sel->can_write();
	       }
	       else {
		   die $SOCKS_ERROR;
	       }

	       # NOTE: when base class ($IO::Socket::Socks::SOCKET_CLASS) is IO::Socket::IP
	       # and you are using kqueue or epoll to check for	readable/writable sockets
	       # you need to readd $sock to kqueue/epoll after each call to ready() (actually until socket will	be connected to	proxy server),
	       # because IO::Socket::IP	may change internal socket of $sock for	milti-homed hosts.
	       # There is no such problem when you are using select/poll
	   }

	   # you may want to return socket to blocking state by	$sock->blocking(1)
	   $sock->syswrite("I am ready");

	accept(	)

       Accept an incoming connection after bind	request. On failed returns
       undef.  On success returns socket. No new socket	created, returned
       socket is same on which this method was called. Because accept(2) is
       not invoked on the client side, socks server calls accept(2) and
       proxify all traffic via socket opened by	client bind request. You can
       call accept only	once on	IO::Socket::Socks client socket.

	command( %cfg )

       Allows one to execute socks command on already opened socket. Thus you
       can create socks	chain. For example see "EXAMPLES" section.

       %cfg is like hash in the	constructor. Only options listed below makes
       sence:

	 ConnectAddr
	 ConnectPort
	 BindAddr
	 BindPort
	 UdpAddr
	 UdpPort
	 SocksVersion
	 SocksDebug
	 SocksResolve
	 AuthType
	 RequireAuth
	 Username
	 Password
	 AuthMethods

       Values of the other options (Timeout for	example) inherited from	the
       constructor.  Options like ProxyAddr and	ProxyPort are not included.

	dst( )

       Return (host, port, address_type) of the	remote host after
       connect/accept or socks server (host, port, address_type) after
       bind/udpassoc.

   Socks Server
       new( %cfg )

       new_from_socket($socket,	%cfg)

       new_from_fd($socket, %cfg)

       Creates a new IO::Socket::Socks server object. new_from_socket()	is the
       same as new(), but allows one to	create object from an existing socket
       (new_from_fd is new_from_socket alias).	Both takes the following
       config hash:

	 SocksVersion => 4 for socks4, 5 for socks5 or [4,5] if	you want accept	both 4 and 5. Default is 5

	 Timeout => Timeout value for various operations

	 Blocking => Since IO::Socket::Socks version 0.6 you can perform non-blocking accept by
		     passing false value for this option. Default is true - blocking. See ready()
		     below for more details.

	 SocksResolve => For socks v5: return destination address to the client
			 in form of 4 bytes if true, otherwise in form of host
			 length	and host name.
			 For socks v4: allow use socks4a protocol extension if
			 true and not otherwise.
			 This overrides	value of $SOCKS4_RESOLVE or $SOCKS5_RESOLVE.
			 See also command_reply().

	 SocksDebug => This will cause all of the SOCKS	traffic	to
		       be presented on the command line	in a form
		       similar to the tables in	the RFCs. This overrides value
		       of $SOCKS_DEBUG variable. Boolean.

	 ProxyAddr => Local host bind address

	 ProxyPort => Local host bind port

	 UserAuth => Reference to a function that returns 1 if client
		     allowed to	use socks server, 0 otherwise. For
		     socks5 proxy it takes login and password as
		     arguments.	For socks4 argument is userid.

	 RequireAuth =>	Not allow anonymous access for socks5 proxy.

	 Listen	=> Same	as IO::Socket::INET listen option. Should be
		   specified as	number > 0.

       The following options should be specified:

	 Listen
	 ProxyAddr
	 ProxyPort

       Other options are facultative.

       accept( )

       Accept an incoming connection and return	a new IO::Socket::Socks	object
       that represents that connection.	 You must call command() on this to
       find out	what the incoming connection wants you to do, and then call
       command_reply() to send back the	reply.

       version(	)

       Returns socks version for socket. It is useful when your	server accepts
       both 4 and 5 version. Then you should know socks	version	to make	proper
       response. Just call "version()" on socket received after	"accept()".

       ready( )

       After non-blocking accept you will get new client socket	object,	which
       may be not ready	to transfer data (if socks handshake is	not done yet).
       ready() will return true	value when handshake will be done successfully
       and false otherwise. Note, socket returned by accept() call will	be
       always in blocking mode.	So if your program can't block you should set
       non-blocking mode for this socket before	ready()	call:
       $socket->blocking(0).  When ready() returns false value you can
       determine what socks handshake needs for	with $SOCKS_ERROR variable. It
       may need	for read, then $SOCKS_ERROR will be SOCKS_WANT_READ or need
       for write, then it will be SOCKS_WANT_WRITE.

       Example:

	 use IO::Socket::Socks;
	 use IO::Select;

	 my $server = IO::Socket::Socks->new(ProxyAddr => 'localhost', ProxyPort => 1080, Blocking => 0)
	     or	die $@;
	 my $select = IO::Select->new($server);
	 $select->can_read(); #	wait for client

	 my $client = $server->accept()
	   or die "accept(): $!	($SOCKS_ERROR)";
	 $client->blocking(0); # !!!
	 $select->add($client);
	 $select->remove($server); # no	more connections

	 while (1) {
	     if	($client->ready) {
		 my $command = $client->command;

		 ... # do client command

		 $client->command_reply(IO::Socket::Socks::REPLY_SUCCESS, $command->[1], $command->[2]);

		 ... # transfer	traffic

		 last;
	     }
	     elsif ($SOCKS_ERROR == SOCKS_WANT_READ) {
		 $select->can_read();
	     }
	     elsif ($SOCKS_ERROR == SOCKS_WANT_WRITE) {
		 $select->can_write();
	     }
	     else {
		 die "Unexpected error:	$SOCKS_ERROR";
	     }
	 }

       command(	)

       After you call accept() the client has sent the command they want you
       to process.  This function should be called on the socket returned by
       accept(). It returns a reference	to an array with the following format:

	 [ COMMAND, ADDRESS, PORT, ADDRESS TYPE	]

       command_reply( REPLY CODE, ADDRESS, PORT	)

       After you call command()	the client needs to be told what the result
       is.  The	REPLY CODE is one of the constants as follows (integer value):

	 For socks v4
	 REQUEST_GRANTED(90): request granted
	 REQUEST_FAILED(91): request rejected or failed
	 REQUEST_REJECTED_IDENTD(92): request rejected because SOCKS server cannot connect to identd on	the client
	 REQUEST_REJECTED_USERID(93): request rejected because the client program and identd report different user-ids

	 For socks v5
	 REPLY_SUCCESS(0): Success
	 REPLY_GENERAL_FAILURE(1): General Failure
	 REPLY_CONN_NOT_ALLOWED(2): Connection Not Allowed
	 REPLY_NETWORK_UNREACHABLE(3): Network Unreachable
	 REPLY_HOST_UNREACHABLE(4): Host Unreachable
	 REPLY_CONN_REFUSED(5):	Connection Refused
	 REPLY_TTL_EXPIRED(6): TTL Expired
	 REPLY_CMD_NOT_SUPPORTED(7): Command Not Supported
	 REPLY_ADDR_NOT_SUPPORTED(8): Address Not Supported

       HOST and	PORT are the resulting host and	port (where server socket
       responsible for this command bound).

       Note: for 5 version "command_reply" will	try to resolve passed address
       if "SocksResolve" has true value	and passed address is domain name. To
       avoid this just pass ip address ("$socket->sockhost") instead of	host
       name or turn off	"SocksResolve" for this	server.	For version 4 passed
       host name will always be	resolved to ip address even if "SocksResolve"
       has false value.	Because	this version doesn't support "ADDRESS" as
       domain name.

VARIABLES
   $SOCKS_ERROR
       This scalar behaves like	$! in that if undef is returned. $SOCKS_ERROR
       is IO::Socket::Socks::Error object with some overloaded operators. In
       string context this variable should contain a string reason for the
       error. In numeric context it contains error code.

   $SOCKS4_RESOLVE
       If this variable	has true value resolving of host names will be done by
       proxy server, otherwise resolving will be done locally. Resolving host
       by socks	proxy version 4	is extension to	the protocol also known	as
       socks4a.	So, only socks4a proxy	supports resolving of hostnames.
       Default value of	this variable is false.	This variable is not
       importable.  See	also `SocksResolve' parameter in the constructor.

   $SOCKS5_RESOLVE
       If this variable	has true value resolving of host names will be done by
       proxy server, otherwise resolving will be done locally. Note: some
       bugous socks5 servers doesn't support resolving of host names. Default
       value is	true. This variable is not importable.	See also
       `SocksResolve' parameter	in the constructor.

   $SOCKS_DEBUG
       Default value is	$ENV{SOCKS_DEBUG}. If this variable has	true value and
       no SocksDebug option in the constructor specified, then SocksDebug will
       has true	value. This variable is	not importable.

   $SOCKET_CLASS
       With this variable you can get/set base socket class for
       "IO::Socket::Socks".  By	default	it tries to use	"IO::Socket::IP" 0.36+
       as socket class.	And falls back to "IO::Socket::INET" if	not available.
       You can set $IO::Socket::Socks::SOCKET_CLASS before loading of
       "IO::Socket::Socks" and then it will not	try to detect proper base
       class itself. You can also set it after loading of "IO::Socket::Socks"
       and this	will automatically update @ISA,	so you shouldn't worry about
       inheritance.

CONSTANTS
       The following constants could be	imported manually or using
       `:constants' tag:

	 SOCKS5_VER
	 SOCKS4_VER
	 ADDR_IPV4
	 ADDR_DOMAINNAME
	 ADDR_IPV6
	 CMD_CONNECT
	 CMD_BIND
	 CMD_UDPASSOC
	 AUTHMECH_ANON
	 AUTHMECH_USERPASS
	 AUTHMECH_INVALID
	 AUTHREPLY_SUCCESS
	 AUTHREPLY_FAILURE
	 ISS_UNKNOWN_ADDRESS # address type sent by client/server not supported	by I::S::S
	 ISS_BAD_VERSION     # socks version sent by client/server != specified	version
	 ISS_CANT_RESOLVE    # I::S::S failed to resolve some host
	 REPLY_SUCCESS
	 REPLY_GENERAL_FAILURE
	 REPLY_CONN_NOT_ALLOWED
	 REPLY_NETWORK_UNREACHABLE
	 REPLY_HOST_UNREACHABLE
	 REPLY_CONN_REFUSED
	 REPLY_TTL_EXPIRED
	 REPLY_CMD_NOT_SUPPORTED
	 REPLY_ADDR_NOT_SUPPORTED
	 REQUEST_GRANTED
	 REQUEST_FAILED
	 REQUEST_REJECTED_IDENTD
	 REQUEST_REJECTED_USERID
	 SOCKS_WANT_READ
	 SOCKS_WANT_WRITE
	 ESOCKSPROTO

       SOCKS_WANT_READ,	SOCKS_WANT_WRITE and ESOCKSPROTO are imported by
       default.

IPv6
       Since version 0.66 "IO::Socket::Socks" supports IPv6 with help of
       IO::Socket::IP 0.36+. And will use "IO::Socket::IP" as base class if
       available. However you can force	set "$SOCKET_CLASS =
       "IO::Socket::INET"" to use IPv4 only. See also "$SOCKET_CLASS"

FAQ
       How to determine	is connection to socks server (client accept) failed
       or some protocol	error occurred?
	   You can check $! variable. If $! == ESOCKSPROTO constant, then it
	   was error in	the protocol. Error description	could be found in
	   $SOCKS_ERROR.

       How to determine	which error in the protocol occurred?
	   You should compare $SOCKS_ERROR with	constants below:

	     AUTHMECH_INVALID
	     AUTHREPLY_FAILURE
	     ISS_UNKNOWN_ADDRESS
	     ISS_BAD_VERSION
	     REPLY_GENERAL_FAILURE
	     REPLY_CONN_NOT_ALLOWED
	     REPLY_NETWORK_UNREACHABLE
	     REPLY_HOST_UNREACHABLE
	     REPLY_CONN_REFUSED
	     REPLY_TTL_EXPIRED
	     REPLY_CMD_NOT_SUPPORTED
	     REPLY_ADDR_NOT_SUPPORTED
	     REQUEST_FAILED
	     REQUEST_REJECTED_IDENTD
	     REQUEST_REJECTED_USERID

BUGS
       The following options are not implemented:

       GSSAPI authentication
       UDP server side support

       Patches are welcome.

SEE ALSO
       IO::Socket::Socks::Wrapper

AUTHOR
       Original	author is Ryan Eatmon

       Now maintained by Oleg G	<oleg@cpan.org>

COPYRIGHT
       This module is free software, you can redistribute it and/or modify it
       under the terms of LGPL.

perl v5.24.1			  2017-05-04		  IO::Socket::Socks(3)

NAME | SYNOPSIS | DESCRIPTION | EXAMPLES | METHODS | VARIABLES | CONSTANTS | IPv6 | FAQ | BUGS | SEE ALSO | AUTHOR | COPYRIGHT

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=IO::Socket::Socks&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help