The SOCKS5BytestreamsServer is an implementation of a SOCKS5 server.
You can use it if you're reachable by your SOCKS5Bytestreams peers, thus avoiding use of an external proxy.
Instantiate with an unfirewalled port
Add your external IP addresses with #add_address
Once you've got an outgoing SOCKS5BytestreamsInitiator, do
SOCKS5BytestreamsInitiator#add_streamhost(my_socks5bytestreamsserver)
before you do SOCKS5BytestreamsInitiator#open
Start a local SOCKS5BytestreamsServer
Will start to listen on the given TCP port and accept new peers
TCP port to listen on
Optional address for the server socket to listen on (i.e. '0.0.0.0' or '::')
# File lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb, line 27 def initialize(port, listen_on=nil) @port = port @addresses = [] @peers = [] @peers_lock = Mutex.new if listen_on socket = TCPServer.new(listen_on, port) else socket = TCPServer.new(port) end Thread.new do Thread.current.abort_on_exception = true loop do peer = SOCKS5BytestreamsPeer.new(socket.accept) Thread.new do Thread.current.abort_on_exception = true begin peer.start rescue Jabber::debuglog("SOCKS5 BytestreamsServer: Error accepting peer: #{$!}") end end @peers_lock.synchronize do @peers << peer end end end end
Add an external IP address
This is a must-have, as SOCKS5BytestreamsInitiator must inform the target where to connect
# File lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb, line 104 def add_address(address) @addresses << address end
Iterate through all configured addresses, yielding SOCKS5BytestreamsServerStreamHost instances, which should be passed to Jabber::Bytestreams::SOCKS5BytestreamsInitiator#add_streamhost
This will be automatically invoked if you pass an instance of SOCKS5BytestreamsServer to Jabber::Bytestreams::SOCKS5BytestreamsInitiator#add_streamhost
My Jabber-ID
# File lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb, line 118 def each_streamhost(my_jid, &block) @addresses.each { |address| yield SOCKS5BytestreamsServerStreamHost.new(self, my_jid, address, @port) } end
Find the socket a peer is associated to
This method also performs some housekeeping, ie. removing peers with closed sockets.
Address like Jabber::Bytestreams::SOCKS5Bytestreams#stream_address
or [nil]
# File lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb, line 64 def peer_sock(addr) res = nil @peers_lock.synchronize { removes = [] @peers.each { |peer| if peer.socket and peer.socket.closed? # Queue peers with closed socket for removal removes << peer elsif peer.address == addr and res.nil? res = peer.socket end # If we sent multiple addresses of our own, clients may # connect multiple times. DO NOT close any other connections # here. These may belong to other concurrent bytestreams, # believe that the peer will close any unneeded sockets # which will then be picked up by the next call to peer_sock. } # If we sent multiple addresses of our own, clients may # connect multiple times. Close these connections here. @peers.delete_if { |peer| if removes.include? peer peer.socket.close rescue IOError true else false end } } res end