Class: Jabber::Bytestreams::SOCKS5BytestreamsInitiator

Inherits:
SOCKS5Bytestreams show all
Defined in:
lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb

Overview

SOCKS5Bytestreams implementation for the initiator side

Instance Attribute Summary collapse

Attributes inherited from SOCKS5Bytestreams

#connect_timeout, #streamhost_used

Instance Method Summary collapse

Methods inherited from SOCKS5Bytestreams

#add_streamhost_callback, #close, #flush, query_streamhost, #read, #write

Constructor Details

#initialize(stream, session_id, initiator_jid, target_jid) ⇒ SOCKS5BytestreamsInitiator

Returns a new instance of SOCKS5BytestreamsInitiator.



8
9
10
11
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb', line 8

def initialize(stream, session_id, initiator_jid, target_jid)
  super
  @streamhosts = []
end

Instance Attribute Details

#streamhostsObject (readonly)

Returns the value of attribute streamhosts.



6
7
8
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb', line 6

def streamhosts
  @streamhosts
end

Instance Method Details

#add_streamhost(streamhost) ⇒ Object

Add a streamhost which will be offered to the target

streamhost

can be:

  • StreamHost

    if already got all information (host/port)

  • SOCKS5BytestreamsServer

    if this is the local streamhost

  • String

    or [JID] if information should be automatically resolved by SOCKS5Bytestreams::query_streamhost



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb', line 20

def add_streamhost(streamhost)
  if streamhost.kind_of?(StreamHost)
    @streamhosts << streamhost
  elsif streamhost.kind_of?(SOCKS5BytestreamsServer)
    streamhost.each_streamhost(@initiator_jid) { |sh|
      @streamhosts << sh
    }
  elsif streamhost.kind_of?(String) or streamhost.kind_of?(JID)
    @streamhosts << SOCKS5Bytestreams::query_streamhost(@stream, streamhost, @initiator_jid)
  else
    raise "Unknwon streamhost type: #{streamhost.class}"
  end
end

#openObject

Send the configured streamhosts to the target, wait for an answer and connect to the host the target chose.



38
39
40
41
42
43
44
45
46
47
48
49
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
82
# File 'lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb', line 38

def open
  iq1 = Iq::new(:set, @target_jid)
  iq1.from = @initiator_jid
  bs = iq1.add IqQueryBytestreams.new(@session_id)
  @streamhosts.each { |se|
    bs.add(se)
  }

  peer_used = nil
  @stream.send_with_id(iq1) { |response|
    if response.type == :result and response.query.kind_of?(IqQueryBytestreams)
      peer_used = response.query.streamhost_used
      raise "No streamhost-used" unless peer_used
      raise "Invalid streamhost-used" unless peer_used.jid
    end
    true
  }

  @streamhost_used = nil
  @streamhosts.each { |sh|
    if peer_used.jid == sh.jid
      @streamhost_used = sh
      break
    end
  }
  if @streamhost_used.jid == @initiator_jid
    # This is our own JID, so the target chose SOCKS5BytestreamsServer
    @socks = @streamhost_used.server.peer_sock(stream_address)
    raise "Target didn't connect" unless @socks
    @streamhost_cbs.process(@streamhost_used, :success, nil)
  else
    begin
      @socks = connect_socks(@streamhost_used)
    rescue Exception => e
      Jabber::debuglog("SOCKS5 Bytestreams: #{e.class}: #{e}\n#{e.backtrace.join("\n")}")
      @streamhost_cbs.process(@streamhost_used, :failure, e)
      raise e
    end
    iq2 = Iq::new(:set, @streamhost_used.jid)
    iq2.add(IqQueryBytestreams.new(@session_id)).activate = @target_jid.to_s
    @stream.send_with_id(iq2) { |reply|
      reply.type == :result
    }
  end
end