@@ -241,6 +241,7 @@ private IRubyObject connectImpl(final ThreadContext context, final boolean block
241241 handshakeStatus = engine .getHandshakeStatus ();
242242 initialHandshake = true ;
243243 }
244+ callRenegotiationCallback (context );
244245 final IRubyObject ex = doHandshake (blocking , exception );
245246 if ( ex != null ) return ex ; // :wait_readable | :wait_writable
246247 }
@@ -324,6 +325,7 @@ private IRubyObject acceptImpl(final ThreadContext context, final boolean blocki
324325 handshakeStatus = engine .getHandshakeStatus ();
325326 initialHandshake = true ;
326327 }
328+ callRenegotiationCallback (context );
327329 final IRubyObject ex = doHandshake (blocking , exception );
328330 if ( ex != null ) return ex ; // :wait_readable | :wait_writable
329331 }
@@ -591,6 +593,18 @@ private int writeToChannel(ByteBuffer buffer, boolean blocking) throws IOExcepti
591593 private void finishInitialHandshake () {
592594 initialHandshake = false ;
593595 }
596+
597+ private void callRenegotiationCallback (final ThreadContext context ) throws RaiseException {
598+ IRubyObject renegotiationCallback = sslContext .getInstanceVariable ("@renegotiation_cb" );
599+ if (renegotiationCallback == null || renegotiationCallback .isNil ()) {
600+ return ;
601+ }
602+ else {
603+ // the return of the Proc is not important
604+ // Can throw ruby exception to "disallow" renegotiations
605+ renegotiationCallback .callMethod (context , "call" , this );
606+ }
607+ }
594608
595609 public int write (ByteBuffer src , boolean blocking ) throws SSLException , IOException {
596610 if ( initialHandshake ) {
0 commit comments