Class: Jabber::Bytestreams::SOCKS5BytestreamsServer

Inherits:
Object
  • Object
show all
Defined in:
lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb

Overview

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.

Usage:

  • Instantiate with an unfirewalled port

  • Add your external IP addresses with SOCKS5BytestreamsServer#add_address

  • Once you’ve got an outgoing SOCKS5BytestreamsInitiator, do SOCKS5BytestreamsInitiator#add_streamhost(my_socks5bytestreamsserver) before you do SOCKS5BytestreamsInitiator#open

Instance Method Summary collapse

Constructor Details

#initialize(port) ⇒ SOCKS5BytestreamsServer

Start a local SOCKS5BytestreamsServer

Will start to listen on the given TCP port and accept new peers

port
Fixnum

TCP port to listen on



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb', line 22

def initialize(port)
  @port = port
  @addresses = []
  @peers = []
  @peers_lock = Mutex.new
  socket = TCPServer.new(port)

  Thread.new {
    loop {
      peer = SOCKS5BytestreamsPeer.new(socket.accept)
      Thread.new {
        begin
          peer.start
        rescue
          Jabber::debuglog("SOCKS5 BytestreamsServer: Error accepting peer: #{$!}")
        end
      }
      @peers_lock.synchronize {
        @peers << peer
      }
    }
  }
end

Instance Method Details

#add_address(address) ⇒ Object

Add an external IP address

This is a must-have, as SOCKS5BytestreamsInitiator must inform the target where to connect



88
89
90
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb', line 88

def add_address(address)
  @addresses << address
end

#each_streamhost(my_jid, &block) ⇒ Object

Iterate through all configured addresses, yielding SOCKS5BytestreamsServerStreamHost instances, which should be passed to SOCKS5BytestreamsInitiator#add_streamhost

This will be automatically invoked if you pass an instance of SOCKS5BytestreamsServer to SOCKS5BytestreamsInitiator#add_streamhost

my_jid
JID

My Jabber-ID



102
103
104
105
106
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb', line 102

def each_streamhost(my_jid, &block)
  @addresses.each { |address|
    yield SOCKS5BytestreamsServerStreamHost.new(self, my_jid, address, @port)
  }
end

#peer_sock(addr) ⇒ Object

Find the socket a peer is associated to

addr
String

Address like SOCKS5Bytestreams#stream_address

result
TCPSocker

or [nil]



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb', line 50

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
      else
        # If we sent multiple addresses of our own, clients may
        # connect multiple times. Close these connections here.
        removes << peer
      end
    }

    # 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