@@ -217,59 +217,75 @@ def handshake!(socket)
217217 raise Error ::HandshakeError , "Cannot handshake because there is no usable socket"
218218 end
219219
220+ response = average_rtt = nil
220221 @server . handle_handshake_failure! do
221- response , exc , rtt , average_rtt =
222- @server . monitor . round_trip_time_averager . measure do
223- socket . write ( app_metadata . ismaster_bytes )
224- Protocol ::Message . deserialize ( socket , max_message_size ) . documents [ 0 ]
225- end
222+ begin
223+ response , exc , rtt , average_rtt =
224+ @server . monitor . round_trip_time_averager . measure do
225+ socket . write ( app_metadata . ismaster_bytes )
226+ Protocol ::Message . deserialize ( socket , max_message_size ) . documents [ 0 ]
227+ end
226228
227- if exc
228- raise exc
229+ if exc
230+ raise exc
231+ end
232+ rescue => e
233+ log_warn ( "Failed to handshake with #{ address } : #{ e . class } : #{ e } " )
234+ raise
229235 end
236+ end
230237
231- if response [ "ok" ] == 1
232- # Auth mechanism is entirely dependent on the contents of
233- # ismaster response *for this connection*.
234- # Ismaster received by the monitoring connection should advertise
235- # the same wire protocol, but if it doesn't, we use whatever
236- # the monitoring connection advertised for filling out the
237- # server description and whatever the non-monitoring connection
238- # (that's this one) advertised for performing auth on that
239- # connection.
240- @auth_mechanism = if response [ 'saslSupportedMechs' ]
241- if response [ 'saslSupportedMechs' ] . include? ( Mongo ::Auth ::SCRAM ::SCRAM_SHA_256_MECHANISM )
242- :scram256
243- else
244- :scram
245- end
238+ post_handshake ( response , average_rtt )
239+ end
240+
241+ # This is a separate method to keep the nesting level down.
242+ def post_handshake ( response , average_rtt )
243+ if response [ "ok" ] == 1
244+ # Auth mechanism is entirely dependent on the contents of
245+ # ismaster response *for this connection*.
246+ # Ismaster received by the monitoring connection should advertise
247+ # the same wire protocol, but if it doesn't, we use whatever
248+ # the monitoring connection advertised for filling out the
249+ # server description and whatever the non-monitoring connection
250+ # (that's this one) advertised for performing auth on that
251+ # connection.
252+ @auth_mechanism = if response [ 'saslSupportedMechs' ]
253+ if response [ 'saslSupportedMechs' ] . include? ( Mongo ::Auth ::SCRAM ::SCRAM_SHA_256_MECHANISM )
254+ :scram256
246255 else
247- # MongoDB servers < 2.6 are no longer suported.
248- # Wire versions should always be returned in ismaster.
249- # See also https://jira.mongodb.org/browse/RUBY-1584.
250- min_wire_version = response [ Description ::MIN_WIRE_VERSION ]
251- max_wire_version = response [ Description ::MAX_WIRE_VERSION ]
252- features = Description ::Features . new ( min_wire_version ..max_wire_version )
253- if features . scram_sha_1_enabled?
254- :scram
255- else
256- :mongodb_cr
257- end
256+ :scram
258257 end
259258 else
260- @auth_mechanism = nil
259+ # MongoDB servers < 2.6 are no longer suported.
260+ # Wire versions should always be returned in ismaster.
261+ # See also https://jira.mongodb.org/browse/RUBY-1584.
262+ min_wire_version = response [ Description ::MIN_WIRE_VERSION ]
263+ max_wire_version = response [ Description ::MAX_WIRE_VERSION ]
264+ features = Description ::Features . new ( min_wire_version ..max_wire_version )
265+ if features . scram_sha_1_enabled?
266+ :scram
267+ else
268+ :mongodb_cr
269+ end
261270 end
262-
263- new_description = Description . new ( address , response , average_rtt )
264- @server . monitor . publish ( Event ::DESCRIPTION_CHANGED , @server . description , new_description )
271+ else
272+ @auth_mechanism = nil
265273 end
274+
275+ new_description = Description . new ( address , response , average_rtt )
276+ @server . monitor . publish ( Event ::DESCRIPTION_CHANGED , @server . description , new_description )
266277 end
267278
268279 def authenticate! ( pending_connection )
269280 if options [ :user ] || options [ :auth_mech ]
270281 user = Auth ::User . new ( Options ::Redacted . new ( :auth_mech => default_mechanism ) . merge ( options ) )
271282 @server . handle_auth_failure! do
272- Auth . get ( user ) . login ( pending_connection )
283+ begin
284+ Auth . get ( user ) . login ( pending_connection )
285+ rescue => e
286+ log_warn ( "Failed to handshake with #{ address } : #{ e . class } : #{ e } " )
287+ raise
288+ end
273289 end
274290 end
275291 end
0 commit comments