14
14
// limitations under the License.
15
15
16
16
// mqba_authenticator.h -*-C++-*-
17
+ #include < bdlmt_timereventscheduler.h>
17
18
#include < mqba_authenticator.h>
18
19
19
20
#include < mqbscm_version.h>
@@ -55,9 +56,6 @@ namespace mqba {
55
56
56
57
namespace {
57
58
BALL_LOG_SET_NAMESPACE_CATEGORY (" MQBA.AUTHENTICATOR" );
58
-
59
- const int k_AUTHENTICATION_READTIMEOUT = 3 * 60 ; // 3 minutes
60
-
61
59
}
62
60
63
61
// -------------------
@@ -224,7 +222,6 @@ void Authenticator::authenticate(
224
222
&result,
225
223
authenticateRequest.mechanism (),
226
224
authenticationData);
227
-
228
225
if (rc != 0 ) {
229
226
BALL_LOG_ERROR << " Authentication failed for connection '"
230
227
<< channel->peerUri () << " ' with mechanism '"
@@ -282,7 +279,10 @@ void Authenticator::authenticate(
282
279
rc,
283
280
sendResponseErrorStream.str (),
284
281
bsl::shared_ptr<mqbnet::Session>());
282
+ return ; // RETURN
285
283
}
284
+
285
+ setTimer (context, result, channel);
286
286
}
287
287
}
288
288
@@ -338,7 +338,7 @@ void Authenticator::reAuthenticate(
338
338
authenticateRequest.mechanism (),
339
339
authenticationData);
340
340
if (rc != 0 ) {
341
- BALL_LOG_ERROR << " Authentication failed for connection '"
341
+ BALL_LOG_ERROR << " Reauthentication failed for connection '"
342
342
<< channel->peerUri () << " ' with mechanism '"
343
343
<< authenticateRequest.mechanism () << " ' [rc: " << rc
344
344
<< " , error: " << authenticationErrorStream.str ()
@@ -356,13 +356,14 @@ void Authenticator::reAuthenticate(
356
356
channel,
357
357
context->authenticationEncodingType ());
358
358
359
- bmqio::Status status (bmqio::StatusCategory::e_GENERIC_ERROR,
360
- " reAuthenticationError" ,
361
- rc,
362
- d_allocator_p);
363
- channel->close (status);
359
+ cleanupOnError (rc, " reauthenticationError" , context, channel);
364
360
}
365
361
else {
362
+ // Authentication succeeded
363
+ BALL_LOG_INFO << " Reauthentication succeeded for connection '"
364
+ << channel->peerUri () << " ' with mechanism '"
365
+ << authenticateRequest.mechanism () << " '" ;
366
+
366
367
response.status ().code () = 0 ;
367
368
response.status ().category () = bmqp_ctrlmsg::StatusCategory::E_SUCCESS;
368
369
response.lifetimeMs () = result->lifetimeMs ();
@@ -375,11 +376,7 @@ void Authenticator::reAuthenticate(
375
376
BALL_LOG_ERROR << " Failed to set (re)authentication state for '"
376
377
<< channel->peerUri ()
377
378
<< " ' to 'e_AUTHENTICATED' from 'e_AUTHENTICATING'" ;
378
- bmqio::Status status (bmqio::StatusCategory::e_GENERIC_ERROR,
379
- " reAuthenticationError" ,
380
- rc,
381
- d_allocator_p);
382
- channel->close (status);
379
+ cleanupOnError (rc, " reauthenticationError" , context, channel);
383
380
return ; // RETURN
384
381
}
385
382
@@ -391,12 +388,11 @@ void Authenticator::reAuthenticate(
391
388
context->authenticationEncodingType ());
392
389
393
390
if (rc != 0 ) {
394
- bmqio::Status status (bmqio::StatusCategory::e_GENERIC_ERROR,
395
- " reAuthenticationError" ,
396
- rc,
397
- d_allocator_p);
398
- channel->close (status);
391
+ cleanupOnError (rc, " reauthenticationError" , context, channel);
392
+ return ; // RETURN
399
393
}
394
+
395
+ setTimer (context, result, channel);
400
396
}
401
397
}
402
398
@@ -411,6 +407,8 @@ Authenticator::Authenticator(
411
407
100 , // max threads
412
408
bsls::TimeInterval (120 ).totalMilliseconds(), // idle time
413
409
allocator)
410
+ , d_scheduler(bdlmt::TimerEventScheduler(bsls::SystemClockType::e_MONOTONIC,
411
+ allocator))
414
412
, d_blobSpPool_p(blobSpPool)
415
413
, d_allocator_p(allocator)
416
414
{
@@ -432,6 +430,15 @@ int Authenticator::start(bsl::ostream& errorDescription)
432
430
return rc; // RETURN
433
431
}
434
432
433
+ rc = d_scheduler.start ();
434
+ if (rc != 0 ) {
435
+ errorDescription << " Failed to start TimerEventScheduler for "
436
+ " Authenticator [rc: "
437
+ << rc << " ]" ;
438
+ d_threadPool.stop ();
439
+ return rc; // RETURN
440
+ }
441
+
435
442
return 0 ;
436
443
}
437
444
@@ -514,6 +521,82 @@ int Authenticator::handleReauthentication(
514
521
return rc;
515
522
}
516
523
524
+ void Authenticator::timeout (const ChannelSp& channel)
525
+ {
526
+ BALL_LOG_DEBUG << " Authentication timeout for channel: "
527
+ << channel->peerUri ();
528
+
529
+ bmqio::Status status (bmqio::StatusCategory::e_TIMEOUT,
530
+ " authenticationTimeout" ,
531
+ -1 ,
532
+ d_allocator_p);
533
+ channel->close (status);
534
+ }
535
+
536
+ void Authenticator::setTimer (const AuthenticationContextSp& context,
537
+ const AuthenticationResultSp& result,
538
+ const ChannelSp& channel)
539
+ {
540
+ if (!result->lifetimeMs ().has_value ()) {
541
+ BALL_LOG_INFO
542
+ << " Lifetime not set for authentication timer for channel: "
543
+ << channel->peerUri () << " , this indicates an infinite lifetime." ;
544
+ return ; // RETURN
545
+ }
546
+
547
+ bslmt::LockGuard<bslmt::Mutex> guard (
548
+ &context->authenticationTimerHandleMutex ()); // MUTEX LOCKED
549
+
550
+ bdlmt::TimerEventScheduler::Handle handle =
551
+ context->authenticationTimerHandle ();
552
+
553
+ // If the timer handle is invalid, it means that this is the initial
554
+ // authentication and the timer has not been set yet.
555
+ if (handle == bdlmt::TimerEventScheduler::INVALID_HANDLE) {
556
+ handle = d_scheduler.scheduleEvent (
557
+ bsls::TimeInterval (result->lifetimeMs ().value ()),
558
+ bdlf::BindUtil::bind (&Authenticator::timeout, this , channel));
559
+ context->setAuthenticationTimerHandle (handle);
560
+ }
561
+ else {
562
+ d_scheduler.cancelEvent (handle);
563
+
564
+ int rc = d_scheduler.rescheduleEvent (
565
+ handle,
566
+ bsls::TimeInterval (result->lifetimeMs ().value ()));
567
+
568
+ if (rc != 0 ) {
569
+ BALL_LOG_ERROR << " Failed to reschedule authentication timer for '"
570
+ << channel->peerUri () << " ' [rc: " << rc
571
+ << " , lifetime: " << result->lifetimeMs ().value ()
572
+ << " ]" ;
573
+ bmqio::Status status (bmqio::StatusCategory::e_GENERIC_ERROR,
574
+ " reAuthenticationError" ,
575
+ rc,
576
+ d_allocator_p);
577
+ channel->close (status);
578
+ }
579
+ }
580
+ }
581
+
582
+ void Authenticator::cleanupOnError (int errorCode,
583
+ const bsl::string& errorDescription,
584
+ const AuthenticationContextSp& context,
585
+ const ChannelSp& channel)
586
+ {
587
+ {
588
+ bslmt::LockGuard<bslmt::Mutex> guard (
589
+ &context->authenticationTimerHandleMutex ()); // MUTEX LOCKED
590
+ d_scheduler.cancelEvent (context->authenticationTimerHandle ());
591
+ }
592
+
593
+ bmqio::Status status (bmqio::StatusCategory::e_GENERIC_ERROR,
594
+ errorDescription,
595
+ errorCode,
596
+ d_allocator_p);
597
+ channel->close (status);
598
+ }
599
+
517
600
int Authenticator::authenticationOutboundOrReverse (
518
601
const AuthenticationContextSp& context)
519
602
{
0 commit comments