| Class | Jabber::Connection |
| In: |
lib/xmpp4r/connection.rb
|
| Parent: | Stream |
The connection class manages the TCP connection to the Jabber server
| allow_tls | [RW] | Allow TLS negotiation? Defaults to true |
| features_timeout | [RW] | How many seconds to wait for <stream:features/> before proceeding |
| host | [R] | |
| keepalive_interval | [RW] | Keep-alive interval in seconds, defaults to 60 (see private method keepalive_loop for implementation details) |
| port | [R] | |
| ssl_capath | [RW] | Optional CA-Path for TLS-handshake |
| ssl_verifycb | [RW] | Optional callback for verification of SSL peer |
| use_ssl | [RW] | whether to use the old and deprecated SSL protocol Defaults to false |
Create a new connection to the given host and port
# File lib/xmpp4r/connection.rb, line 41
41: def initialize
42: super()
43: @host = nil
44: @port = nil
45: @allow_tls = defined? OpenSSL
46: @tls = false
47: @ssl_capath = nil
48: @ssl_verifycb = nil
49: @features_timeout = 10
50: @keepalive_interval = 60
51: @use_ssl = false
52: end
# File lib/xmpp4r/connection.rb, line 95
95: def accept_features
96: begin
97: Timeout::timeout(@features_timeout) {
98: Jabber::debuglog("FEATURES: waiting...")
99: @features_sem.wait
100: Jabber::debuglog("FEATURES: waiting finished")
101: }
102: rescue Timeout::Error
103: Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
104: end
105:
106: if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
107: begin
108: starttls
109: rescue
110: Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
111: end
112: end
113: end
Closing connection: first kill keepaliveThread, then call Stream#close!
# File lib/xmpp4r/connection.rb, line 90
90: def close!
91: @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive?
92: super
93: end
Connect to the Jabber server through a TCP Socket, start the Jabber parser, invoke to accept_features to wait for TLS, start the keep-alive thread
# File lib/xmpp4r/connection.rb, line 59
59: def connect(host, port)
60: @host = host
61: @port = port
62: # Reset is_tls?, so that it works when reconnecting
63: @tls = false
64:
65: Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
66: @socket = TCPSocket.new(@host, @port)
67:
68: # We want to use the old and deprecated SSL protocol (usually on port 5223)
69: if @use_ssl
70: ssl = OpenSSL::SSL::SSLSocket.new(@socket)
71: ssl.connect # start SSL session
72: ssl.sync_close = true
73: Jabber::debuglog("SSL connection established.")
74: @socket = ssl
75: end
76:
77: start
78:
79: accept_features
80:
81: @keepaliveThread = Thread.new do
82: Thread.current.abort_on_exception = true
83: keepalive_loop
84: end
85: end
Have we gone to TLS mode?
| result: | [true] or [false] |
# File lib/xmpp4r/connection.rb, line 181
181: def is_tls?
182: @tls
183: end
Start the parser on the previously connected socket
# File lib/xmpp4r/connection.rb, line 117
117: def start
118: super(@socket)
119: end
Do a <starttls/> (will be automatically done by connect if stream peer supports this)
# File lib/xmpp4r/connection.rb, line 124
124: def starttls
125: stls = REXML::Element.new('starttls')
126: stls.add_namespace('urn:ietf:params:xml:ns:xmpp-tls')
127:
128: reply = nil
129: send(stls) { |r|
130: reply = r
131: true
132: }
133: if reply.name != 'proceed'
134: raise ServerError(reply.first_element('error'))
135: end
136: # Don't be interrupted
137: stop
138:
139: begin
140: error = nil
141:
142: # Context/user set-able stuff
143: ctx = OpenSSL::SSL::SSLContext.new
144: if @ssl_capath
145: ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
146: ctx.ca_path = @ssl_capath
147: else
148: ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
149: end
150: ctx.verify_callback = @ssl_verifycb
151:
152: # SSL connection establishing
153: sslsocket = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
154: sslsocket.sync_close = true
155: Jabber::debuglog("TLSv1: OpenSSL handshake in progress")
156: sslsocket.connect
157:
158: # Make REXML believe it's a real socket
159: class << sslsocket
160: def kind_of?(o)
161: o == IO ? true : super
162: end
163: end
164:
165: # We're done and will use it
166: @tls = true
167: @socket = sslsocket
168: rescue
169: error = $!
170: ensure
171: Jabber::debuglog("TLSv1: restarting parser")
172: start
173: accept_features
174: raise error if error
175: end
176: end