00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 #include <ptlib.h>
00604
00605 #ifdef __GNUC__
00606 #pragma implementation "gkclient.h"
00607 #endif
00608
00609 #if defined(_WIN32) && (_MSC_VER > 1300)
00610 #pragma warning(disable:4244) // warning about possible loss of data
00611 #endif
00612
00613 #include "gkclient.h"
00614
00615 #include "h323ep.h"
00616 #include "h323rtp.h"
00617 #include "h323pdu.h"
00618
00619 #ifdef H323_H460
00620 #include "h460/h4601.h"
00621 #endif
00622
00623 #define new PNEW
00624
00625
00626 static PTimeInterval AdjustTimeout(unsigned seconds)
00627 {
00628
00629 static unsigned TimeoutDeadband = 5;
00630
00631 return PTimeInterval(0, seconds > TimeoutDeadband
00632 ? (seconds - TimeoutDeadband)
00633 : TimeoutDeadband);
00634 }
00635
00636
00638
00639 H323Gatekeeper::H323Gatekeeper(H323EndPoint & ep, H323Transport * trans)
00640 : H225_RAS(ep, trans),
00641 requestMutex(1, 1),
00642 authenticators(ep.CreateAuthenticators())
00643 #ifdef H323_H460
00644 ,features(ep.GetFeatureSet())
00645 #endif
00646 {
00647 alternatePermanent = FALSE;
00648 discoveryComplete = FALSE;
00649 registrationFailReason = UnregisteredLocally;
00650
00651 pregrantMakeCall = pregrantAnswerCall = RequireARQ;
00652
00653 autoReregister = TRUE;
00654 reregisterNow = FALSE;
00655 requiresDiscovery = FALSE;
00656
00657 timeToLive.SetNotifier(PCREATE_NOTIFIER(TickleMonitor));
00658 infoRequestRate.SetNotifier(PCREATE_NOTIFIER(TickleMonitor));
00659
00660 willRespondToIRR = FALSE;
00661 monitorStop = FALSE;
00662
00663 monitor = PThread::Create(PCREATE_NOTIFIER(MonitorMain), 0,
00664 PThread::NoAutoDeleteThread,
00665 PThread::NormalPriority,
00666 "GkMonitor:%x");
00667 #ifdef H323_H460
00668 features.LoadFeatureSet(H460_Feature::FeatureRas);
00669 #endif
00670
00671 localId = PString();
00672 assignedGK = NULL;
00673 }
00674
00675
00676 H323Gatekeeper::~H323Gatekeeper()
00677 {
00678 if (monitor != NULL) {
00679 monitorStop = TRUE;
00680 monitorTickle.Signal();
00681 monitor->WaitForTermination();
00682 delete monitor;
00683 }
00684
00685 StopChannel();
00686 }
00687
00688
00689 PString H323Gatekeeper::GetName() const
00690 {
00691 PStringStream s;
00692 s << *this;
00693 return s;
00694 }
00695
00696
00697 BOOL H323Gatekeeper::DiscoverAny()
00698 {
00699 gatekeeperIdentifier = PString();
00700 return StartDiscovery(H323TransportAddress());
00701 }
00702
00703
00704 BOOL H323Gatekeeper::DiscoverByName(const PString & identifier)
00705 {
00706 gatekeeperIdentifier = identifier;
00707 return StartDiscovery(H323TransportAddress());
00708 }
00709
00710
00711 BOOL H323Gatekeeper::DiscoverByAddress(const H323TransportAddress & address)
00712 {
00713 gatekeeperIdentifier = PString();
00714 return StartDiscovery(address);
00715 }
00716
00717
00718 BOOL H323Gatekeeper::DiscoverByNameAndAddress(const PString & identifier,
00719 const H323TransportAddress & address)
00720 {
00721 gatekeeperIdentifier = identifier;
00722 return StartDiscovery(address);
00723 }
00724
00725 BOOL H323Gatekeeper::StartDiscovery(const H323TransportAddress & initialAddress)
00726 {
00727 if (PAssertNULL(transport) == NULL)
00728 return FALSE;
00729
00731 if (!endpoint.GetSendGRQ() && !initialAddress.IsEmpty()) {
00732 transport->SetRemoteAddress(initialAddress);
00733 if (!transport->Connect()) {
00734 PTRACE(2, "RAS\tUnable to connect to gatekeeper at " << initialAddress);
00735 return FALSE;
00736 }
00737 transport->SetPromiscuous(H323Transport::AcceptFromRemoteOnly);
00738 StartChannel();
00739 PTRACE(2, "RAS\tSkipping gatekeeper discovery for " << initialAddress);
00740 return TRUE;
00741 }
00742
00743 H323RasPDU pdu;
00744 Request request(SetupGatekeeperRequest(pdu), pdu);
00745
00746 H323TransportAddress address = initialAddress;
00747 request.responseInfo = &address;
00748
00749 requestsMutex.Wait();
00750 requests.SetAt(request.sequenceNumber, &request);
00751 requestsMutex.Signal();
00752
00753 discoveryComplete = FALSE;
00754 unsigned retries = endpoint.GetGatekeeperRequestRetries();
00755 while (!discoveryComplete) {
00756 if (transport->DiscoverGatekeeper(*this, pdu, address)) {
00757 if (address == initialAddress)
00758 break;
00760 }
00761 else {
00762
00763 if (--retries == 0)
00764 break;
00765 }
00766 }
00767
00768 requestsMutex.Wait();
00769 requests.SetAt(request.sequenceNumber, NULL);
00770 requestsMutex.Signal();
00771
00772 if (discoveryComplete) {
00773 if (transport->Connect())
00774 StartChannel();
00775 }
00776
00777 return discoveryComplete;
00778 }
00779
00780
00781 unsigned H323Gatekeeper::SetupGatekeeperRequest(H323RasPDU & request)
00782 {
00783 if (PAssertNULL(transport) == NULL)
00784 return 0;
00785
00786 H225_GatekeeperRequest & grq = request.BuildGatekeeperRequest(GetNextSequenceNumber());
00787
00788 endpoint.SetEndpointTypeInfo(grq.m_endpointType);
00789 transport->SetUpTransportPDU(grq.m_rasAddress, TRUE);
00790
00791 grq.IncludeOptionalField(H225_GatekeeperRequest::e_endpointAlias);
00792 H323SetAliasAddresses(endpoint.GetAliasNames(), grq.m_endpointAlias);
00793
00794 if (!gatekeeperIdentifier) {
00795 grq.IncludeOptionalField(H225_GatekeeperRequest::e_gatekeeperIdentifier);
00796 grq.m_gatekeeperIdentifier = gatekeeperIdentifier;
00797 }
00798
00799 grq.IncludeOptionalField(H225_GatekeeperRequest::e_supportsAltGK);
00800
00801 grq.IncludeOptionalField(H225_GatekeeperRequest::e_supportsAssignedGK);
00802 grq.m_supportsAssignedGK = TRUE;
00803
00804 OnSendGatekeeperRequest(grq);
00805
00806 discoveryComplete = FALSE;
00807
00808 return grq.m_requestSeqNum;
00809 }
00810
00811
00812 void H323Gatekeeper::OnSendGatekeeperRequest(H225_GatekeeperRequest & grq)
00813 {
00814 H225_RAS::OnSendGatekeeperRequest(grq);
00815
00816 for (PINDEX i = 0; i < authenticators.GetSize(); i++) {
00817 if (authenticators[i].SetCapability(grq.m_authenticationCapability, grq.m_algorithmOIDs)) {
00818 grq.IncludeOptionalField(H225_GatekeeperRequest::e_authenticationCapability);
00819 grq.IncludeOptionalField(H225_GatekeeperRequest::e_algorithmOIDs);
00820 }
00821 }
00822 }
00823
00824
00825 BOOL H323Gatekeeper::OnReceiveGatekeeperConfirm(const H225_GatekeeperConfirm & gcf)
00826 {
00827 if (!H225_RAS::OnReceiveGatekeeperConfirm(gcf))
00828 return FALSE;
00829
00830 PINDEX i;
00831
00832 for (i = 0; i < authenticators.GetSize(); i++) {
00833 H235Authenticator & authenticator = authenticators[i];
00834 if (authenticator.UseGkAndEpIdentifiers())
00835 authenticator.SetRemoteId(gatekeeperIdentifier);
00836 }
00837
00838 if (gcf.HasOptionalField(H225_GatekeeperConfirm::e_authenticationMode) &&
00839 gcf.HasOptionalField(H225_GatekeeperConfirm::e_algorithmOID)) {
00840 for (i = 0; i < authenticators.GetSize(); i++) {
00841 H235Authenticator & authenticator = authenticators[i];
00842 authenticator.Enable(authenticator.IsCapability(gcf.m_authenticationMode,
00843 gcf.m_algorithmOID));
00844 PTRACE(4,"RAS\tAuthenticator " << authenticator.GetName()
00845 << (authenticator.IsActive() ? " ACTIVATED" : " disabled"));
00846 }
00847 }
00848
00849 H323TransportAddress locatedAddress = gcf.m_rasAddress;
00850 PTRACE(2, "RAS\tGatekeeper discovery found " << locatedAddress);
00851
00852 if (!transport->SetRemoteAddress(locatedAddress)) {
00853 PTRACE(2, "RAS\tInvalid gatekeeper discovery address: \"" << locatedAddress << '"');
00854 return FALSE;
00855 }
00856
00857 if (gcf.HasOptionalField(H225_GatekeeperConfirm::e_alternateGatekeeper))
00858 SetAlternates(gcf.m_alternateGatekeeper, FALSE);
00859
00860 if (gcf.HasOptionalField(H225_GatekeeperConfirm::e_assignedGatekeeper)) {
00861 SetAssignedGatekeeper(gcf.m_assignedGatekeeper);
00862 PTRACE(2, "RAS\tAssigned Gatekeeper redirected " << assignedGK);
00863
00864 if (lastRequest->responseInfo != NULL) {
00865 H323TransportAddress & gkAddress = *(H323TransportAddress *)lastRequest->responseInfo;
00866 gkAddress = assignedGK->rasAddress;
00867 gatekeeperIdentifier = PString();
00868 }
00869 } else {
00870 endpoint.OnGatekeeperConfirm();
00871 discoveryComplete = TRUE;
00872 }
00873 return TRUE;
00874 }
00875
00876
00877 BOOL H323Gatekeeper::OnReceiveGatekeeperReject(const H225_GatekeeperReject & grj)
00878 {
00879 if (!H225_RAS::OnReceiveGatekeeperReject(grj))
00880 return FALSE;
00881
00882 if (grj.HasOptionalField(H225_GatekeeperReject::e_altGKInfo)) {
00883 SetAlternates(grj.m_altGKInfo.m_alternateGatekeeper,
00884 grj.m_altGKInfo.m_altGKisPermanent);
00885 }
00886
00887 if ((alternates.GetSize() > 0) && (lastRequest->responseInfo != NULL)) {
00888 H323TransportAddress & gkAddress = *(H323TransportAddress *)lastRequest->responseInfo;
00889 gkAddress = alternates[0].rasAddress;
00890 }
00891
00892 endpoint.OnGatekeeperReject();
00893
00894 return TRUE;
00895 }
00896
00897
00898 BOOL H323Gatekeeper::RegistrationRequest(BOOL autoReg)
00899 {
00900 if (PAssertNULL(transport) == NULL)
00901 return FALSE;
00902
00903 autoReregister = autoReg;
00904
00905 H323RasPDU pdu;
00906 H225_RegistrationRequest & rrq = pdu.BuildRegistrationRequest(GetNextSequenceNumber());
00907
00908
00909 rrq.m_discoveryComplete = discoveryComplete;
00910
00911
00912 H323TransportAddress newaddress;
00913 if ((!discoveryComplete) && (endpoint.GatekeeperCheckIP(transport->GetRemoteAddress(),newaddress)))
00914 transport->SetRemoteAddress(newaddress);
00915
00916 rrq.m_rasAddress.SetSize(1);
00917 transport->SetUpTransportPDU(rrq.m_rasAddress[0], TRUE);
00918
00919 H323TransportAddressArray listeners = endpoint.GetInterfaceAddresses(TRUE, transport);
00920 if (listeners.IsEmpty()) {
00921 PTRACE(1, "RAS\tCannot register with Gatekeeper without a H323Listener!");
00922 return FALSE;
00923 }
00924
00925 H323SetTransportAddresses(*transport, listeners, rrq.m_callSignalAddress);
00926
00927 endpoint.SetEndpointTypeInfo(rrq.m_terminalType);
00928 endpoint.SetVendorIdentifierInfo(rrq.m_endpointVendor);
00929
00930 if (!IsRegistered()) {
00931 rrq.IncludeOptionalField(H225_RegistrationRequest::e_terminalAlias);
00932 H323SetAliasAddresses(endpoint.GetAliasNames(), rrq.m_terminalAlias);
00933 for (PINDEX i = 0; i < authenticators.GetSize(); i++) {
00934 H235Authenticator & authenticator = authenticators[i];
00935 if (authenticator.UseGkAndEpIdentifiers())
00936 authenticator.SetLocalId(localId);
00937 }
00938 }
00939
00940 rrq.m_willSupplyUUIEs = TRUE;
00941 rrq.IncludeOptionalField(H225_RegistrationRequest::e_usageReportingCapability);
00942 rrq.m_usageReportingCapability.IncludeOptionalField(H225_RasUsageInfoTypes::e_startTime);
00943 rrq.m_usageReportingCapability.IncludeOptionalField(H225_RasUsageInfoTypes::e_endTime);
00944 rrq.m_usageReportingCapability.IncludeOptionalField(H225_RasUsageInfoTypes::e_terminationCause);
00945 rrq.IncludeOptionalField(H225_RegistrationRequest::e_supportsAltGK);
00946
00947 if (!gatekeeperIdentifier) {
00948 rrq.IncludeOptionalField(H225_RegistrationRequest::e_gatekeeperIdentifier);
00949 rrq.m_gatekeeperIdentifier = gatekeeperIdentifier;
00950 }
00951
00952 if (!endpointIdentifier.IsEmpty()) {
00953 rrq.IncludeOptionalField(H225_RegistrationRequest::e_endpointIdentifier);
00954 rrq.m_endpointIdentifier = endpointIdentifier;
00955 }
00956
00957 PTimeInterval ttl = endpoint.GetGatekeeperTimeToLive();
00958 if (ttl > 0) {
00959 rrq.IncludeOptionalField(H225_RegistrationRequest::e_timeToLive);
00960 rrq.m_timeToLive = (int)ttl.GetSeconds();
00961 }
00962
00963 if (endpoint.CanDisplayAmountString()) {
00964 rrq.IncludeOptionalField(H225_RegistrationRequest::e_callCreditCapability);
00965 rrq.m_callCreditCapability.IncludeOptionalField(H225_CallCreditCapability::e_canDisplayAmountString);
00966 rrq.m_callCreditCapability.m_canDisplayAmountString = TRUE;
00967 }
00968
00969 if (endpoint.CanEnforceDurationLimit()) {
00970 rrq.IncludeOptionalField(H225_RegistrationRequest::e_callCreditCapability);
00971 rrq.m_callCreditCapability.IncludeOptionalField(H225_CallCreditCapability::e_canEnforceDurationLimit);
00972 rrq.m_callCreditCapability.m_canEnforceDurationLimit = TRUE;
00973 }
00974
00975 if (assignedGK != NULL) {
00976 rrq.IncludeOptionalField(H225_RegistrationRequest::e_assignedGatekeeper);
00977 rrq.m_assignedGatekeeper = assignedGK->GetAlternate();
00978 }
00979
00980 if (IsRegistered()) {
00981 rrq.IncludeOptionalField(H225_RegistrationRequest::e_keepAlive);
00982 rrq.m_keepAlive = TRUE;
00983 }
00984
00985
00986 discoveryComplete = FALSE;
00987
00988 Request request(rrq.m_requestSeqNum, pdu);
00989 if (MakeRequest(request))
00990 return TRUE;
00991
00992 PTRACE(3, "RAS\tFailed registration of " << endpointIdentifier << " with " << gatekeeperIdentifier);
00993 switch (request.responseResult) {
00994 case Request::RejectReceived :
00995 switch (request.rejectReason) {
00996 case H225_RegistrationRejectReason::e_discoveryRequired :
00997
00998
00999 requiresDiscovery = TRUE;
01000
01001
01002 case H225_RegistrationRejectReason::e_fullRegistrationRequired :
01003 registrationFailReason = GatekeeperLostRegistration;
01004
01005 reregisterNow = TRUE;
01006 monitorTickle.Signal();
01007 break;
01008
01009
01010 case H225_RegistrationRejectReason::e_invalidCallSignalAddress :
01011 registrationFailReason = InvalidListener;
01012 break;
01013
01014 case H225_RegistrationRejectReason::e_duplicateAlias :
01015 registrationFailReason = DuplicateAlias;
01016 break;
01017
01018 case H225_RegistrationRejectReason::e_securityDenial :
01019 registrationFailReason = SecurityDenied;
01020 break;
01021
01022 default :
01023 registrationFailReason = (RegistrationFailReasons)(request.rejectReason|RegistrationRejectReasonMask);
01024 break;
01025 }
01026 break;
01027
01028 case Request::BadCryptoTokens :
01029 registrationFailReason = SecurityDenied;
01030 break;
01031
01032 default :
01033 registrationFailReason = TransportError;
01034 break;
01035 }
01036
01037 return FALSE;
01038 }
01039
01040
01041 BOOL H323Gatekeeper::OnReceiveRegistrationConfirm(const H225_RegistrationConfirm & rcf)
01042 {
01043 if (!H225_RAS::OnReceiveRegistrationConfirm(rcf))
01044 return FALSE;
01045
01046 registrationFailReason = RegistrationSuccessful;
01047
01048 endpointIdentifier = rcf.m_endpointIdentifier;
01049 PTRACE(3, "RAS\tRegistered " << endpointIdentifier << " with " << gatekeeperIdentifier);
01050
01051 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_assignedGatekeeper))
01052 SetAssignedGatekeeper(rcf.m_assignedGatekeeper);
01053
01054 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_alternateGatekeeper))
01055 SetAlternates(rcf.m_alternateGatekeeper, FALSE);
01056
01057 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_timeToLive))
01058 timeToLive = AdjustTimeout(rcf.m_timeToLive);
01059 else
01060 timeToLive = 0;
01061
01062
01063 if (rcf.m_callSignalAddress.GetSize() > 0)
01064 gkRouteAddress = rcf.m_callSignalAddress[0];
01065
01066 willRespondToIRR = rcf.m_willRespondToIRR;
01067
01068 pregrantMakeCall = pregrantAnswerCall = RequireARQ;
01069 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_preGrantedARQ)) {
01070 if (rcf.m_preGrantedARQ.m_makeCall)
01071 pregrantMakeCall = rcf.m_preGrantedARQ.m_useGKCallSignalAddressToMakeCall
01072 ? PreGkRoutedARQ : PregrantARQ;
01073 if (rcf.m_preGrantedARQ.m_answerCall)
01074 pregrantAnswerCall = rcf.m_preGrantedARQ.m_useGKCallSignalAddressToAnswer
01075 ? PreGkRoutedARQ : PregrantARQ;
01076 if (rcf.m_preGrantedARQ.HasOptionalField(H225_RegistrationConfirm_preGrantedARQ::e_irrFrequencyInCall))
01077 SetInfoRequestRate(AdjustTimeout(rcf.m_preGrantedARQ.m_irrFrequencyInCall));
01078 else
01079 ClearInfoRequestRate();
01080 }
01081 else
01082 ClearInfoRequestRate();
01083
01084
01085
01086 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_terminalAlias) &&
01087 !endpoint.OnGatekeeperAliases(rcf.m_terminalAlias)) {
01088 const PStringList & currentAliases = endpoint.GetAliasNames();
01089 PStringList aliasesToChange;
01090 PINDEX i, j;
01091
01092 for (i = 0; i < rcf.m_terminalAlias.GetSize(); i++) {
01093 PString alias = H323GetAliasAddressString(rcf.m_terminalAlias[i]);
01094 if (!alias) {
01095 for (j = 0; j < currentAliases.GetSize(); j++) {
01096 if (alias *= currentAliases[j])
01097 break;
01098 }
01099 if (j >= currentAliases.GetSize())
01100 aliasesToChange.AppendString(alias);
01101 }
01102 }
01103 for (i = 0; i < aliasesToChange.GetSize(); i++) {
01104 PTRACE(2, "RAS\tGatekeeper add of alias \"" << aliasesToChange[i] << '"');
01105 endpoint.AddAliasName(aliasesToChange[i]);
01106 }
01107
01108 aliasesToChange.RemoveAll();
01109
01110 for (i = 0; i < currentAliases.GetSize(); i++) {
01111 for (j = 0; j < rcf.m_terminalAlias.GetSize(); j++) {
01112 if (currentAliases[i] *= H323GetAliasAddressString(rcf.m_terminalAlias[j]))
01113 break;
01114 }
01115 if (j >= rcf.m_terminalAlias.GetSize())
01116 aliasesToChange.AppendString(currentAliases[i]);
01117 }
01118 for (i = 0; i < aliasesToChange.GetSize(); i++) {
01119 PTRACE(2, "RAS\tGatekeeper removal of alias \"" << aliasesToChange[i] << '"');
01120 endpoint.RemoveAliasName(aliasesToChange[i]);
01121 }
01122 }
01123
01124 #ifdef H323_H248
01125 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_serviceControl))
01126 OnServiceControlSessions(rcf.m_serviceControl, NULL);
01127 #endif
01128
01129
01130 if (rcf.HasOptionalField(H225_RegistrationConfirm::e_nonStandardData))
01131 {
01132 PString NATaddr = rcf.m_nonStandardData.m_data.AsString();
01133 if (!NATaddr.IsEmpty())
01134 if (NATaddr.Left(4) == "NAT=")
01135 endpoint.OnGatekeeperNATDetect(NATaddr.Right(NATaddr.GetLength()-4),endpointIdentifier,gkRouteAddress);
01136 else
01137 endpoint.OnGatekeeperOpenNATDetect(endpointIdentifier,gkRouteAddress);
01138 }
01139
01140 endpoint.OnRegistrationConfirm(gkRouteAddress);
01141
01142 return TRUE;
01143 }
01144
01145
01146 BOOL H323Gatekeeper::OnReceiveRegistrationReject(const H225_RegistrationReject & rrj)
01147 {
01148 if (!H225_RAS::OnReceiveRegistrationReject(rrj))
01149 return FALSE;
01150
01151 if (rrj.HasOptionalField(H225_RegistrationReject::e_assignedGatekeeper))
01152 SetAssignedGatekeeper(rrj.m_assignedGatekeeper);
01153 else if (rrj.HasOptionalField(H225_RegistrationReject::e_altGKInfo))
01154 SetAlternates(rrj.m_altGKInfo.m_alternateGatekeeper,
01155 rrj.m_altGKInfo.m_altGKisPermanent);
01156 else
01157 endpoint.OnRegistrationReject();
01158
01159 return TRUE;
01160 }
01161
01162 void H323Gatekeeper::ReRegisterNow()
01163 {
01164 PTRACE(3, "RAS\tforcing reregistration");
01165 RegistrationTimeToLive();
01166
01167 }
01168
01169 void H323Gatekeeper::RegistrationTimeToLive()
01170 {
01171 PTRACE(3, "RAS\tTime To Live reregistration");
01172
01173 if (requiresDiscovery) {
01174 PTRACE(2, "RAS\tRepeating discovery on gatekeepers request.");
01175
01176 H323RasPDU pdu;
01177 Request request(SetupGatekeeperRequest(pdu), pdu);
01178 if (!MakeRequest(request) || !discoveryComplete) {
01179 PTRACE(2, "RAS\tRediscovery failed, retrying in 1 minute.");
01180 timeToLive = PTimeInterval(0, 0, 1);
01181 return;
01182 }
01183
01184 requiresDiscovery = FALSE;
01185 }
01186
01187 if (!RegistrationRequest(autoReregister)) {
01188 PTRACE_IF(2, !reregisterNow, "RAS\tTime To Live reregistration failed, retrying in 1 minute");
01189 timeToLive = PTimeInterval(0, 0, 1);
01190 }
01191 }
01192
01193
01194 BOOL H323Gatekeeper::UnregistrationRequest(int reason)
01195 {
01196 if (PAssertNULL(transport) == NULL)
01197 return FALSE;
01198
01199 PINDEX i;
01200 H323RasPDU pdu;
01201 H225_UnregistrationRequest & urq = pdu.BuildUnregistrationRequest(GetNextSequenceNumber());
01202
01203 H225_TransportAddress rasAddress;
01204 transport->SetUpTransportPDU(rasAddress, TRUE);
01205
01206 H323SetTransportAddresses(*transport,
01207 endpoint.GetInterfaceAddresses(TRUE, transport),
01208 urq.m_callSignalAddress);
01209
01210 urq.IncludeOptionalField(H225_UnregistrationRequest::e_endpointAlias);
01211 H323SetAliasAddresses(endpoint.GetAliasNames(), urq.m_endpointAlias);
01212
01213 if (!gatekeeperIdentifier) {
01214 urq.IncludeOptionalField(H225_UnregistrationRequest::e_gatekeeperIdentifier);
01215 urq.m_gatekeeperIdentifier = gatekeeperIdentifier;
01216 }
01217
01218 if (!endpointIdentifier.IsEmpty()) {
01219 urq.IncludeOptionalField(H225_UnregistrationRequest::e_endpointIdentifier);
01220 urq.m_endpointIdentifier = endpointIdentifier;
01221 }
01222
01223 if (reason >= 0) {
01224 urq.IncludeOptionalField(H225_UnregistrationRequest::e_reason);
01225 urq.m_reason = reason;
01226 }
01227
01228 Request request(urq.m_requestSeqNum, pdu);
01229
01230 BOOL requestResult = MakeRequest(request);
01231
01232 for (i = 0; i < alternates.GetSize(); i++) {
01233 AlternateInfo & altgk = alternates[i];
01234 if (altgk.registrationState == AlternateInfo::IsRegistered) {
01235 Connect(altgk.rasAddress,altgk.gatekeeperIdentifier);
01236 UnregistrationRequest(reason);
01237 }
01238 }
01239
01240 if (requestResult)
01241 return TRUE;
01242
01243 switch (request.responseResult) {
01244 case Request::NoResponseReceived :
01245 registrationFailReason = TransportError;
01246 timeToLive = 0;
01247 break;
01248
01249 case Request::BadCryptoTokens :
01250 registrationFailReason = SecurityDenied;
01251 timeToLive = 0;
01252 break;
01253
01254 default :
01255 break;
01256 }
01257
01258 return !IsRegistered();
01259 }
01260
01261
01262 BOOL H323Gatekeeper::OnReceiveUnregistrationConfirm(const H225_UnregistrationConfirm & ucf)
01263 {
01264 if (!H225_RAS::OnReceiveUnregistrationConfirm(ucf))
01265 return FALSE;
01266
01267 registrationFailReason = UnregisteredLocally;
01268 timeToLive = 0;
01269
01270 return TRUE;
01271 }
01272
01273
01274 BOOL H323Gatekeeper::OnReceiveUnregistrationRequest(const H225_UnregistrationRequest & urq)
01275 {
01276 if (!H225_RAS::OnReceiveUnregistrationRequest(urq))
01277 return FALSE;
01278
01279 PTRACE(2, "RAS\tUnregistration received");
01280 if (!urq.HasOptionalField(H225_UnregistrationRequest::e_gatekeeperIdentifier) ||
01281 urq.m_gatekeeperIdentifier.GetValue() != gatekeeperIdentifier) {
01282 PTRACE(1, "RAS\tInconsistent gatekeeperIdentifier!");
01283 return FALSE;
01284 }
01285
01286 if (!urq.HasOptionalField(H225_UnregistrationRequest::e_endpointIdentifier) ||
01287 urq.m_endpointIdentifier.GetValue() != endpointIdentifier) {
01288 PTRACE(1, "RAS\tInconsistent endpointIdentifier!");
01289 return FALSE;
01290 }
01291
01292 endpoint.ClearAllCalls(H323Connection::EndedByGatekeeper, FALSE);
01293
01294 PTRACE(3, "RAS\tUnregistered, calls cleared");
01295 registrationFailReason = UnregisteredByGatekeeper;
01296 timeToLive = 0;
01297
01298 if (urq.HasOptionalField(H225_UnregistrationRequest::e_alternateGatekeeper))
01299 SetAlternates(urq.m_alternateGatekeeper, FALSE);
01300
01301 H323RasPDU response(authenticators);
01302 response.BuildUnregistrationConfirm(urq.m_requestSeqNum);
01303 BOOL ok = WritePDU(response);
01304
01305 if (autoReregister) {
01306 PTRACE(3, "RAS\tReregistering by setting timeToLive");
01307 reregisterNow = TRUE;
01308 monitorTickle.Signal();
01309 }
01310
01311 endpoint.OnUnRegisterRequest();
01312
01313 return ok;
01314 }
01315
01316
01317 BOOL H323Gatekeeper::OnReceiveUnregistrationReject(const H225_UnregistrationReject & urj)
01318 {
01319 if (!H225_RAS::OnReceiveUnregistrationReject(urj))
01320 return FALSE;
01321
01322 if (lastRequest->rejectReason != H225_UnregRejectReason::e_callInProgress) {
01323 registrationFailReason = UnregisteredLocally;
01324 timeToLive = 0;
01325 }
01326
01327 return TRUE;
01328 }
01329
01330
01331 BOOL H323Gatekeeper::LocationRequest(const PString & alias,
01332 H323TransportAddress & address)
01333 {
01334 PStringList aliases;
01335 aliases.AppendString(alias);
01336 return LocationRequest(aliases, address);
01337 }
01338
01339
01340 BOOL H323Gatekeeper::LocationRequest(const PStringList & aliases,
01341 H323TransportAddress & address)
01342 {
01343 if (PAssertNULL(transport) == NULL)
01344 return FALSE;
01345
01346 H323RasPDU pdu;
01347 H225_LocationRequest & lrq = pdu.BuildLocationRequest(GetNextSequenceNumber());
01348
01349 H323SetAliasAddresses(aliases, lrq.m_destinationInfo);
01350
01351 if (!endpointIdentifier.IsEmpty()) {
01352 lrq.IncludeOptionalField(H225_LocationRequest::e_endpointIdentifier);
01353 lrq.m_endpointIdentifier = endpointIdentifier;
01354 }
01355
01356 transport->SetUpTransportPDU(lrq.m_replyAddress, TRUE);
01357
01358 lrq.IncludeOptionalField(H225_LocationRequest::e_sourceInfo);
01359 H323SetAliasAddresses(endpoint.GetAliasNames(), lrq.m_sourceInfo);
01360
01361 if (!gatekeeperIdentifier) {
01362 lrq.IncludeOptionalField(H225_LocationRequest::e_gatekeeperIdentifier);
01363 lrq.m_gatekeeperIdentifier = gatekeeperIdentifier;
01364 }
01365
01366 Request request(lrq.m_requestSeqNum, pdu);
01367 request.responseInfo = &address;
01368 if (!MakeRequest(request))
01369 return FALSE;
01370
01371
01372 PIPSocket::Address ipAddr;
01373 WORD port;
01374 return address.GetIpAndPort(ipAddr, port) && (port != 0);
01375 }
01376
01377
01378 H323Gatekeeper::AdmissionResponse::AdmissionResponse()
01379 {
01380 rejectReason = UINT_MAX;
01381
01382 gatekeeperRouted = FALSE;
01383 endpointCount = 1;
01384 transportAddress = NULL;
01385 accessTokenData = NULL;
01386
01387 aliasAddresses = NULL;
01388 destExtraCallInfo = NULL;
01389 }
01390
01391
01392 struct AdmissionRequestResponseInfo {
01393 AdmissionRequestResponseInfo(
01394 H323Gatekeeper::AdmissionResponse & r,
01395 H323Connection & c
01396 ) : param(r), connection(c) { }
01397
01398 H323Gatekeeper::AdmissionResponse & param;
01399 H323Connection & connection;
01400 unsigned allocatedBandwidth;
01401 unsigned uuiesRequested;
01402 PString accessTokenOID1;
01403 PString accessTokenOID2;
01404 };
01405
01406
01407 BOOL H323Gatekeeper::AdmissionRequest(H323Connection & connection,
01408 AdmissionResponse & response,
01409 BOOL ignorePreGrantedARQ)
01410 {
01411 BOOL answeringCall = connection.HadAnsweredCall();
01412
01413 if (!ignorePreGrantedARQ) {
01414 switch (answeringCall ? pregrantAnswerCall : pregrantMakeCall) {
01415 case RequireARQ :
01416 break;
01417 case PregrantARQ :
01418 return TRUE;
01419 case PreGkRoutedARQ :
01420 if (gkRouteAddress.IsEmpty()) {
01421 response.rejectReason = UINT_MAX;
01422 return FALSE;
01423 }
01424 if (response.transportAddress != NULL)
01425 *response.transportAddress = gkRouteAddress;
01426 response.gatekeeperRouted = TRUE;
01427 return TRUE;
01428 }
01429 }
01430
01431 H323RasPDU pdu;
01432 H225_AdmissionRequest & arq = pdu.BuildAdmissionRequest(GetNextSequenceNumber());
01433
01434 arq.m_callType.SetTag(H225_CallType::e_pointToPoint);
01435 arq.m_endpointIdentifier = endpointIdentifier;
01436 arq.m_answerCall = answeringCall;
01437 arq.m_canMapAlias = TRUE;
01438
01439 arq.m_willSupplyUUIEs = TRUE;
01440
01441 if (!gatekeeperIdentifier) {
01442 arq.IncludeOptionalField(H225_AdmissionRequest::e_gatekeeperIdentifier);
01443 arq.m_gatekeeperIdentifier = gatekeeperIdentifier;
01444 }
01445
01446 PString destInfo = connection.GetRemotePartyName();
01447 arq.m_srcInfo.SetSize(1);
01448 if (answeringCall) {
01449 H323SetAliasAddress(destInfo, arq.m_srcInfo[0]);
01450 if (!connection.GetLocalPartyName()) {
01451 arq.IncludeOptionalField(H225_AdmissionRequest::e_destinationInfo);
01452 H323SetAliasAddresses(connection.GetLocalAliasNames(), arq.m_destinationInfo);
01453 }
01454 }
01455 else {
01456 H323SetAliasAddresses(connection.GetLocalAliasNames(), arq.m_srcInfo);
01457 if (response.transportAddress == NULL || destInfo != *response.transportAddress) {
01458 arq.IncludeOptionalField(H225_AdmissionRequest::e_destinationInfo);
01459 arq.m_destinationInfo.SetSize(1);
01460 H323SetAliasAddress(destInfo, arq.m_destinationInfo[0]);
01461 }
01462 }
01463
01464 const H323Transport * signallingChannel = connection.GetSignallingChannel();
01465 if (answeringCall) {
01466 arq.IncludeOptionalField(H225_AdmissionRequest::e_srcCallSignalAddress);
01467 signallingChannel->SetUpTransportPDU(arq.m_srcCallSignalAddress, FALSE);
01468 arq.IncludeOptionalField(H225_AdmissionRequest::e_destCallSignalAddress);
01469 signallingChannel->SetUpTransportPDU(arq.m_destCallSignalAddress, TRUE);
01470 }
01471 else {
01472 if (signallingChannel != NULL && signallingChannel->IsOpen()) {
01473 arq.IncludeOptionalField(H225_AdmissionRequest::e_srcCallSignalAddress);
01474 signallingChannel->SetUpTransportPDU(arq.m_srcCallSignalAddress, TRUE);
01475 }
01476 if (response.transportAddress != NULL && !response.transportAddress->IsEmpty()) {
01477 arq.IncludeOptionalField(H225_AdmissionRequest::e_destCallSignalAddress);
01478 response.transportAddress->SetPDU(arq.m_destCallSignalAddress);
01479 }
01480 }
01481
01482 arq.m_bandWidth = connection.GetBandwidthAvailable();
01483 arq.m_callReferenceValue = connection.GetCallReference();
01484 arq.m_conferenceID = connection.GetConferenceIdentifier();
01485 arq.m_callIdentifier.m_guid = connection.GetCallIdentifier();
01486
01487 connection.SetCallLinkage(pdu);
01488
01489 AdmissionRequestResponseInfo info(response, connection);
01490 info.accessTokenOID1 = connection.GetGkAccessTokenOID();
01491 PINDEX comma = info.accessTokenOID1.Find(',');
01492 if (comma == P_MAX_INDEX)
01493 info.accessTokenOID2 = info.accessTokenOID1;
01494 else {
01495 info.accessTokenOID2 = info.accessTokenOID1.Mid(comma+1);
01496 info.accessTokenOID1.Delete(comma, P_MAX_INDEX);
01497 }
01498
01499 connection.OnSendARQ(arq);
01500
01501 Request request(arq.m_requestSeqNum, pdu);
01502 request.responseInfo = &info;
01503
01504 if (!authenticators.IsEmpty()) {
01505 pdu.Prepare(arq.m_tokens, H225_AdmissionRequest::e_tokens,
01506 arq.m_cryptoTokens, H225_AdmissionRequest::e_cryptoTokens);
01507
01508 H235Authenticators adjustedAuthenticators;
01509 if (connection.GetAdmissionRequestAuthentication(arq, adjustedAuthenticators)) {
01510 PTRACE(3, "RAS\tAuthenticators credentials replaced with \""
01511 << setfill(',') << adjustedAuthenticators << setfill(' ') << "\" during ARQ");
01512
01513 for (PINDEX i = 0; i < adjustedAuthenticators.GetSize(); i++) {
01514 H235Authenticator & authenticator = adjustedAuthenticators[i];
01515 if (authenticator.UseGkAndEpIdentifiers())
01516 authenticator.SetRemoteId(gatekeeperIdentifier);
01517 }
01518
01519 adjustedAuthenticators.PreparePDU(pdu,
01520 arq.m_tokens, H225_AdmissionRequest::e_tokens,
01521 arq.m_cryptoTokens, H225_AdmissionRequest::e_cryptoTokens);
01522 pdu.SetAuthenticators(adjustedAuthenticators);
01523 }
01524 }
01525
01526 if (!MakeRequest(request)) {
01527 response.rejectReason = request.rejectReason;
01528
01529
01530 if (request.responseResult == Request::RejectReceived &&
01531 response.rejectReason != H225_AdmissionRejectReason::e_callerNotRegistered &&
01532 response.rejectReason != H225_AdmissionRejectReason::e_invalidEndpointIdentifier)
01533 return FALSE;
01534
01535 PTRACE(2, "RAS\tEndpoint has become unregistered during ARQ from gatekeeper " << gatekeeperIdentifier);
01536
01537
01538 switch (request.responseResult) {
01539 case Request::NoResponseReceived :
01540 registrationFailReason = TransportError;
01541 response.rejectReason = UINT_MAX;
01542 break;
01543
01544 case Request::BadCryptoTokens :
01545 registrationFailReason = SecurityDenied;
01546 response.rejectReason = H225_AdmissionRejectReason::e_securityDenial;
01547 break;
01548
01549 default :
01550 registrationFailReason = GatekeeperLostRegistration;
01551 }
01552
01553
01554 if (!autoReregister)
01555 return FALSE;
01556
01557
01558 if (!RegistrationRequest(autoReregister))
01559 return FALSE;
01560
01561
01562 arq.m_endpointIdentifier = endpointIdentifier;
01563 if (!gatekeeperIdentifier) {
01564 arq.IncludeOptionalField(H225_AdmissionRequest::e_gatekeeperIdentifier);
01565 arq.m_gatekeeperIdentifier = gatekeeperIdentifier;
01566 }
01567 else
01568 arq.RemoveOptionalField(H225_AdmissionRequest::e_gatekeeperIdentifier);
01569
01570
01571 arq.m_requestSeqNum = GetNextSequenceNumber();
01572 request.sequenceNumber = arq.m_requestSeqNum;
01573
01574 if (!MakeRequest(request)) {
01575 response.rejectReason = request.responseResult == Request::RejectReceived
01576 ? request.rejectReason : UINT_MAX;
01577
01578 return FALSE;
01579 }
01580 }
01581
01582 connection.SetBandwidthAvailable(info.allocatedBandwidth);
01583 connection.SetUUIEsRequested(info.uuiesRequested);
01584
01585 return TRUE;
01586 }
01587
01588
01589 void H323Gatekeeper::OnSendAdmissionRequest(H225_AdmissionRequest & )
01590 {
01591
01592
01593 }
01594
01595
01596 static unsigned GetUUIEsRequested(const H225_UUIEsRequested & pdu)
01597 {
01598 unsigned uuiesRequested = 0;
01599
01600 if ((BOOL)pdu.m_setup)
01601 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_setup);
01602 if ((BOOL)pdu.m_callProceeding)
01603 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_callProceeding);
01604 if ((BOOL)pdu.m_connect)
01605 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_connect);
01606 if ((BOOL)pdu.m_alerting)
01607 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_alerting);
01608 if ((BOOL)pdu.m_information)
01609 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_information);
01610 if ((BOOL)pdu.m_releaseComplete)
01611 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_releaseComplete);
01612 if ((BOOL)pdu.m_facility)
01613 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_facility);
01614 if ((BOOL)pdu.m_progress)
01615 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_progress);
01616 if ((BOOL)pdu.m_empty)
01617 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_empty);
01618
01619 if (pdu.HasOptionalField(H225_UUIEsRequested::e_status) && (BOOL)pdu.m_status)
01620 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_status);
01621 if (pdu.HasOptionalField(H225_UUIEsRequested::e_statusInquiry) && (BOOL)pdu.m_statusInquiry)
01622 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_statusInquiry);
01623 if (pdu.HasOptionalField(H225_UUIEsRequested::e_setupAcknowledge) && (BOOL)pdu.m_setupAcknowledge)
01624 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_setupAcknowledge);
01625 if (pdu.HasOptionalField(H225_UUIEsRequested::e_notify) && (BOOL)pdu.m_notify)
01626 uuiesRequested |= (1<<H225_H323_UU_PDU_h323_message_body::e_notify);
01627
01628 return uuiesRequested;
01629 }
01630
01631
01632 static void ExtractToken(const AdmissionRequestResponseInfo & info,
01633 const H225_ArrayOf_ClearToken & tokens,
01634 PBYTEArray & accessTokenData)
01635 {
01636 if (!info.accessTokenOID1 && tokens.GetSize() > 0) {
01637 PTRACE(4, "Looking for OID " << info.accessTokenOID1 << " in ACF to copy.");
01638 for (PINDEX i = 0; i < tokens.GetSize(); i++) {
01639 if (tokens[i].m_tokenOID == info.accessTokenOID1) {
01640 PTRACE(4, "Looking for OID " << info.accessTokenOID2 << " in token to copy.");
01641 if (tokens[i].HasOptionalField(H235_ClearToken::e_nonStandard) &&
01642 tokens[i].m_nonStandard.m_nonStandardIdentifier == info.accessTokenOID2) {
01643 PTRACE(4, "Copying ACF nonStandard OctetString.");
01644 accessTokenData = tokens[i].m_nonStandard.m_data;
01645 break;
01646 }
01647 }
01648 }
01649 }
01650 }
01651
01652
01653 BOOL H323Gatekeeper::OnReceiveAdmissionConfirm(const H225_AdmissionConfirm & acf)
01654 {
01655 if (!H225_RAS::OnReceiveAdmissionConfirm(acf))
01656 return FALSE;
01657
01658 AdmissionRequestResponseInfo & info = *(AdmissionRequestResponseInfo *)lastRequest->responseInfo;
01659 info.allocatedBandwidth = acf.m_bandWidth;
01660 if (info.param.transportAddress != NULL)
01661 *info.param.transportAddress = acf.m_destCallSignalAddress;
01662
01663 info.param.gatekeeperRouted = acf.m_callModel.GetTag() == H225_CallModel::e_gatekeeperRouted;
01664
01665
01666
01667 if (info.param.aliasAddresses != NULL &&
01668 acf.HasOptionalField(H225_AdmissionConfirm::e_destinationInfo)) {
01669 PTRACE(3, "RAS\tGatekeeper specified " << acf.m_destinationInfo.GetSize() << " aliases in ACF");
01670 *info.param.aliasAddresses = acf.m_destinationInfo;
01671 }
01672
01673 if (acf.HasOptionalField(H225_AdmissionConfirm::e_uuiesRequested))
01674 info.uuiesRequested = GetUUIEsRequested(acf.m_uuiesRequested);
01675
01676 if (info.param.destExtraCallInfo != NULL &&
01677 acf.HasOptionalField(H225_AdmissionConfirm::e_destExtraCallInfo))
01678 *info.param.destExtraCallInfo = acf.m_destExtraCallInfo;
01679
01680 if (info.param.accessTokenData != NULL && acf.HasOptionalField(H225_AdmissionConfirm::e_tokens))
01681 ExtractToken(info, acf.m_tokens, *info.param.accessTokenData);
01682
01683 if (info.param.transportAddress != NULL) {
01684 PINDEX count = 1;
01685 for (PINDEX i = 0; i < acf.m_alternateEndpoints.GetSize() && count < info.param.endpointCount; i++) {
01686 if (acf.m_alternateEndpoints[i].HasOptionalField(H225_Endpoint::e_callSignalAddress) &&
01687 acf.m_alternateEndpoints[i].m_callSignalAddress.GetSize() > 0) {
01688 info.param.transportAddress[count] = acf.m_alternateEndpoints[i].m_callSignalAddress[0];
01689 if (info.param.accessTokenData != NULL)
01690 ExtractToken(info, acf.m_alternateEndpoints[i].m_tokens, info.param.accessTokenData[count]);
01691 count++;
01692 }
01693 }
01694 info.param.endpointCount = count;
01695 }
01696
01697 if (acf.HasOptionalField(H225_AdmissionConfirm::e_irrFrequency))
01698 SetInfoRequestRate(AdjustTimeout(acf.m_irrFrequency));
01699 willRespondToIRR = acf.m_willRespondToIRR;
01700
01701 info.connection.OnReceivedACF(acf);
01702
01703 #ifdef H323_H248
01704 if (acf.HasOptionalField(H225_AdmissionConfirm::e_serviceControl))
01705 OnServiceControlSessions(acf.m_serviceControl, &info.connection);
01706 #endif
01707
01708 return TRUE;
01709 }
01710
01711
01712 BOOL H323Gatekeeper::OnReceiveAdmissionReject(const H225_AdmissionReject & arj)
01713 {
01714 if (!H225_RAS::OnReceiveAdmissionReject(arj))
01715 return FALSE;
01716
01717 AdmissionRequestResponseInfo & info = *(AdmissionRequestResponseInfo *)lastRequest->responseInfo;
01718 info.connection.OnReceivedARJ(arj);
01719
01720 #ifdef H323_H248
01721 if (arj.HasOptionalField(H225_AdmissionConfirm::e_serviceControl))
01722 OnServiceControlSessions(arj.m_serviceControl,&info.connection);
01723 #endif
01724
01725 return TRUE;
01726 }
01727
01728
01729 static void SetRasUsageInformation(const H323Connection & connection,
01730 H225_RasUsageInformation & usage)
01731 {
01732 unsigned time = connection.GetAlertingTime().GetTimeInSeconds();
01733 if (time != 0) {
01734 usage.IncludeOptionalField(H225_RasUsageInformation::e_alertingTime);
01735 usage.m_alertingTime = time;
01736 }
01737
01738 time = connection.GetConnectionStartTime().GetTimeInSeconds();
01739 if (time != 0) {
01740 usage.IncludeOptionalField(H225_RasUsageInformation::e_connectTime);
01741 usage.m_connectTime = time;
01742 }
01743
01744 time = connection.GetConnectionEndTime().GetTimeInSeconds();
01745 if (time != 0) {
01746 usage.IncludeOptionalField(H225_RasUsageInformation::e_endTime);
01747 usage.m_endTime = time;
01748 }
01749 }
01750
01751
01752 BOOL H323Gatekeeper::DisengageRequest(const H323Connection & connection, unsigned reason)
01753 {
01754 H323RasPDU pdu;
01755 H225_DisengageRequest & drq = pdu.BuildDisengageRequest(GetNextSequenceNumber());
01756
01757 drq.m_endpointIdentifier = endpointIdentifier;
01758 drq.m_conferenceID = connection.GetConferenceIdentifier();
01759 drq.m_callReferenceValue = connection.GetCallReference();
01760 drq.m_callIdentifier.m_guid = connection.GetCallIdentifier();
01761 drq.m_disengageReason.SetTag(reason);
01762 drq.m_answeredCall = connection.HadAnsweredCall();
01763
01764 drq.IncludeOptionalField(H225_DisengageRequest::e_usageInformation);
01765 SetRasUsageInformation(connection, drq.m_usageInformation);
01766
01767 drq.IncludeOptionalField(H225_DisengageRequest::e_terminationCause);
01768 drq.m_terminationCause.SetTag(H225_CallTerminationCause::e_releaseCompleteReason);
01769 Q931::CauseValues cause = H323TranslateFromCallEndReason(connection, drq.m_terminationCause);
01770 if (cause != Q931::ErrorInCauseIE) {
01771 drq.m_terminationCause.SetTag(H225_CallTerminationCause::e_releaseCompleteCauseIE);
01772 PASN_OctetString & rcReason = drq.m_terminationCause;
01773 rcReason.SetSize(2);
01774 rcReason[0] = 0x80;
01775 rcReason[1] = (BYTE)(0x80|cause);
01776 }
01777
01778 if (!gatekeeperIdentifier) {
01779 drq.IncludeOptionalField(H225_DisengageRequest::e_gatekeeperIdentifier);
01780 drq.m_gatekeeperIdentifier = gatekeeperIdentifier;
01781 }
01782
01783 connection.OnSendDRQ(drq);
01784
01785 Request request(drq.m_requestSeqNum, pdu);
01786 return MakeRequestWithReregister(request, H225_DisengageRejectReason::e_notRegistered);
01787 }
01788
01789
01790 BOOL H323Gatekeeper::OnReceiveDisengageRequest(const H225_DisengageRequest & drq)
01791 {
01792 if (!H225_RAS::OnReceiveDisengageRequest(drq))
01793 return FALSE;
01794
01795 OpalGloballyUniqueID id = NULL;
01796 if (drq.HasOptionalField(H225_DisengageRequest::e_callIdentifier))
01797 id = drq.m_callIdentifier.m_guid;
01798 if (id == NULL)
01799 id = drq.m_conferenceID;
01800
01801 H323RasPDU response(authenticators);
01802 H323Connection * connection = endpoint.FindConnectionWithLock(id.AsString());
01803 if (connection == NULL)
01804 response.BuildDisengageReject(drq.m_requestSeqNum,
01805 H225_DisengageRejectReason::e_requestToDropOther);
01806 else {
01807 H225_DisengageConfirm & dcf = response.BuildDisengageConfirm(drq.m_requestSeqNum);
01808
01809 dcf.IncludeOptionalField(H225_DisengageConfirm::e_usageInformation);
01810 SetRasUsageInformation(*connection, dcf.m_usageInformation);
01811
01812 connection->ClearCall(H323Connection::EndedByGatekeeper);
01813 connection->Unlock();
01814 }
01815
01816 #ifdef H323_H248
01817 if (drq.HasOptionalField(H225_DisengageRequest::e_serviceControl))
01818 OnServiceControlSessions(drq.m_serviceControl, connection);
01819 #endif
01820
01821 return WritePDU(response);
01822 }
01823
01824
01825 BOOL H323Gatekeeper::BandwidthRequest(H323Connection & connection,
01826 unsigned requestedBandwidth)
01827 {
01828 H323RasPDU pdu;
01829 H225_BandwidthRequest & brq = pdu.BuildBandwidthRequest(GetNextSequenceNumber());
01830
01831 brq.m_endpointIdentifier = endpointIdentifier;
01832 brq.m_conferenceID = connection.GetConferenceIdentifier();
01833 brq.m_callReferenceValue = connection.GetCallReference();
01834 brq.m_callIdentifier.m_guid = connection.GetCallIdentifier();
01835 brq.m_bandWidth = requestedBandwidth;
01836 brq.IncludeOptionalField(H225_BandwidthRequest::e_usageInformation);
01837 SetRasUsageInformation(connection, brq.m_usageInformation);
01838
01839 Request request(brq.m_requestSeqNum, pdu);
01840
01841 unsigned allocatedBandwidth;
01842 request.responseInfo = &allocatedBandwidth;
01843
01844 if (!MakeRequestWithReregister(request, H225_BandRejectReason::e_notBound))
01845 return FALSE;
01846
01847 connection.SetBandwidthAvailable(allocatedBandwidth);
01848 return TRUE;
01849 }
01850
01851
01852 BOOL H323Gatekeeper::OnReceiveBandwidthConfirm(const H225_BandwidthConfirm & bcf)
01853 {
01854 if (!H225_RAS::OnReceiveBandwidthConfirm(bcf))
01855 return FALSE;
01856
01857 if (lastRequest->responseInfo != NULL)
01858 *(unsigned *)lastRequest->responseInfo = bcf.m_bandWidth;
01859
01860 return TRUE;
01861 }
01862
01863
01864 BOOL H323Gatekeeper::OnReceiveBandwidthRequest(const H225_BandwidthRequest & brq)
01865 {
01866 if (!H225_RAS::OnReceiveBandwidthRequest(brq))
01867 return FALSE;
01868
01869 OpalGloballyUniqueID id = brq.m_callIdentifier.m_guid;
01870 H323Connection * connection = endpoint.FindConnectionWithLock(id.AsString());
01871
01872 H323RasPDU response(authenticators);
01873 if (connection == NULL)
01874 response.BuildBandwidthReject(brq.m_requestSeqNum,
01875 H225_BandRejectReason::e_invalidConferenceID);
01876 else {
01877 if (connection->SetBandwidthAvailable(brq.m_bandWidth))
01878 response.BuildBandwidthConfirm(brq.m_requestSeqNum, brq.m_bandWidth);
01879 else
01880 response.BuildBandwidthReject(brq.m_requestSeqNum,
01881 H225_BandRejectReason::e_insufficientResources);
01882 connection->Unlock();
01883 }
01884
01885 return WritePDU(response);
01886 }
01887
01888
01889 void H323Gatekeeper::SetInfoRequestRate(const PTimeInterval & rate)
01890 {
01891 if (rate < infoRequestRate.GetResetTime() || infoRequestRate.GetResetTime() == 0) {
01892
01893
01894 PTimeInterval timeToGo = infoRequestRate;
01895 infoRequestRate = rate;
01896 if (rate > timeToGo)
01897 infoRequestRate.PTimeInterval::operator=(timeToGo);
01898 }
01899 }
01900
01901
01902 void H323Gatekeeper::ClearInfoRequestRate()
01903 {
01904
01905 if (endpoint.GetAllConnections().IsEmpty())
01906 infoRequestRate = 0;
01907 }
01908
01909
01910 H225_InfoRequestResponse & H323Gatekeeper::BuildInfoRequestResponse(H323RasPDU & response,
01911 unsigned seqNum)
01912 {
01913 H225_InfoRequestResponse & irr = response.BuildInfoRequestResponse(seqNum);
01914
01915 endpoint.SetEndpointTypeInfo(irr.m_endpointType);
01916 irr.m_endpointIdentifier = endpointIdentifier;
01917 transport->SetUpTransportPDU(irr.m_rasAddress, TRUE);
01918 H323SetTransportAddresses(*transport,
01919 endpoint.GetInterfaceAddresses(TRUE, transport),
01920 irr.m_callSignalAddress);
01921
01922 irr.IncludeOptionalField(H225_InfoRequestResponse::e_endpointAlias);
01923 H323SetAliasAddresses(endpoint.GetAliasNames(), irr.m_endpointAlias);
01924
01925 return irr;
01926 }
01927
01928
01929 BOOL H323Gatekeeper::SendUnsolicitedIRR(H225_InfoRequestResponse & irr,
01930 H323RasPDU & response)
01931 {
01932 irr.m_unsolicited = TRUE;
01933
01934 if (willRespondToIRR) {
01935 PTRACE(4, "RAS\tSending unsolicited IRR and awaiting acknowledgement");
01936 Request request(irr.m_requestSeqNum, response);
01937 return MakeRequest(request);
01938 }
01939
01940 PTRACE(4, "RAS\tSending unsolicited IRR and without acknowledgement");
01941 response.SetAuthenticators(authenticators);
01942 return WritePDU(response);
01943 }
01944
01945
01946 static void AddInfoRequestResponseCall(H225_InfoRequestResponse & irr,
01947 const H323Connection & connection)
01948 {
01949 irr.IncludeOptionalField(H225_InfoRequestResponse::e_perCallInfo);
01950
01951 PINDEX sz = irr.m_perCallInfo.GetSize();
01952 if (!irr.m_perCallInfo.SetSize(sz+1))
01953 return;
01954
01955 H225_InfoRequestResponse_perCallInfo_subtype & info = irr.m_perCallInfo[sz];
01956
01957 info.m_callReferenceValue = connection.GetCallReference();
01958 info.m_callIdentifier.m_guid = connection.GetCallIdentifier();
01959 info.m_conferenceID = connection.GetConferenceIdentifier();
01960 info.IncludeOptionalField(H225_InfoRequestResponse_perCallInfo_subtype::e_originator);
01961 info.m_originator = !connection.HadAnsweredCall();
01962
01963 H323_RTP_Session * session = connection.GetSessionCallbacks(RTP_Session::DefaultAudioSessionID);
01964 if (session != NULL) {
01965 info.IncludeOptionalField(H225_InfoRequestResponse_perCallInfo_subtype::e_audio);
01966 info.m_audio.SetSize(1);
01967 session->OnSendRasInfo(info.m_audio[0]);
01968 }
01969
01970 session = connection.GetSessionCallbacks(RTP_Session::DefaultVideoSessionID);
01971 if (session != NULL) {
01972 info.IncludeOptionalField(H225_InfoRequestResponse_perCallInfo_subtype::e_video);
01973 info.m_video.SetSize(1);
01974 session->OnSendRasInfo(info.m_video[0]);
01975 }
01976
01977 const H323Transport & controlChannel = connection.GetControlChannel();
01978 controlChannel.SetUpTransportPDU(info.m_h245.m_recvAddress, TRUE);
01979 controlChannel.SetUpTransportPDU(info.m_h245.m_sendAddress, FALSE);
01980
01981 info.m_callType.SetTag(H225_CallType::e_pointToPoint);
01982 info.m_bandWidth = connection.GetBandwidthUsed();
01983 info.m_callModel.SetTag(connection.IsGatekeeperRouted() ? H225_CallModel::e_gatekeeperRouted
01984 : H225_CallModel::e_direct);
01985
01986 info.IncludeOptionalField(H225_InfoRequestResponse_perCallInfo_subtype::e_usageInformation);
01987 SetRasUsageInformation(connection, info.m_usageInformation);
01988 }
01989
01990
01991 static BOOL AddAllInfoRequestResponseCall(H225_InfoRequestResponse & irr,
01992 H323EndPoint & endpoint,
01993 const PStringList & tokens)
01994 {
01995 BOOL addedOne = FALSE;
01996
01997 for (PINDEX i = 0; i < tokens.GetSize(); i++) {
01998 H323Connection * connection = endpoint.FindConnectionWithLock(tokens[i]);
01999 if (connection != NULL) {
02000 AddInfoRequestResponseCall(irr, *connection);
02001 connection->OnSendIRR(irr);
02002 connection->Unlock();
02003 addedOne = TRUE;
02004 }
02005 }
02006
02007 return addedOne;
02008 }
02009
02010
02011 void H323Gatekeeper::InfoRequestResponse()
02012 {
02013 PStringList tokens = endpoint.GetAllConnections();
02014 if (tokens.IsEmpty())
02015 return;
02016
02017 H323RasPDU response;
02018 H225_InfoRequestResponse & irr = BuildInfoRequestResponse(response, GetNextSequenceNumber());
02019
02020 if (AddAllInfoRequestResponseCall(irr, endpoint, tokens))
02021 SendUnsolicitedIRR(irr, response);
02022 }
02023
02024
02025 void H323Gatekeeper::InfoRequestResponse(const H323Connection & connection)
02026 {
02027 H323RasPDU response;
02028 H225_InfoRequestResponse & irr = BuildInfoRequestResponse(response, GetNextSequenceNumber());
02029
02030 AddInfoRequestResponseCall(irr, connection);
02031
02032 connection.OnSendIRR(irr);
02033
02034 SendUnsolicitedIRR(irr, response);
02035 }
02036
02037
02038 void H323Gatekeeper::InfoRequestResponse(const H323Connection & connection,
02039 const H225_H323_UU_PDU & pdu,
02040 BOOL sent)
02041 {
02042
02043 if (pdu.m_h323_message_body.GetTag() == P_MAX_INDEX)
02044 return;
02045
02046
02047 if ((connection.GetUUIEsRequested() & (1<<pdu.m_h323_message_body.GetTag())) == 0)
02048 return;
02049
02050 PTRACE(3, "RAS\tSending unsolicited IRR for requested UUIE");
02051
02052
02053 H323RasPDU response;
02054 H225_InfoRequestResponse & irr = BuildInfoRequestResponse(response, GetNextSequenceNumber());
02055
02056 AddInfoRequestResponseCall(irr, connection);
02057
02058 irr.m_perCallInfo[0].IncludeOptionalField(H225_InfoRequestResponse_perCallInfo_subtype::e_pdu);
02059 irr.m_perCallInfo[0].m_pdu.SetSize(1);
02060 irr.m_perCallInfo[0].m_pdu[0].m_sent = sent;
02061 irr.m_perCallInfo[0].m_pdu[0].m_h323pdu = pdu;
02062
02063 connection.OnSendIRR(irr);
02064 SendUnsolicitedIRR(irr, response);
02065 }
02066
02067
02068 BOOL H323Gatekeeper::OnReceiveInfoRequest(const H225_InfoRequest & irq)
02069 {
02070 if (!H225_RAS::OnReceiveInfoRequest(irq))
02071 return FALSE;
02072
02073 H323RasPDU response(authenticators);
02074 H225_InfoRequestResponse & irr = BuildInfoRequestResponse(response, irq.m_requestSeqNum);
02075
02076 if (irq.m_callReferenceValue == 0) {
02077 if (!AddAllInfoRequestResponseCall(irr, endpoint, endpoint.GetAllConnections())) {
02078 irr.IncludeOptionalField(H225_InfoRequestResponse::e_irrStatus);
02079 irr.m_irrStatus.SetTag(H225_InfoRequestResponseStatus::e_invalidCall);
02080 }
02081 }
02082 else {
02083 OpalGloballyUniqueID id = irq.m_callIdentifier.m_guid;
02084 H323Connection * connection = endpoint.FindConnectionWithLock(id.AsString());
02085 if (connection == NULL) {
02086 irr.IncludeOptionalField(H225_InfoRequestResponse::e_irrStatus);
02087 irr.m_irrStatus.SetTag(H225_InfoRequestResponseStatus::e_invalidCall);
02088 }
02089 else {
02090 if (irq.HasOptionalField(H225_InfoRequest::e_uuiesRequested))
02091 connection->SetUUIEsRequested(::GetUUIEsRequested(irq.m_uuiesRequested));
02092
02093 AddInfoRequestResponseCall(irr, *connection);
02094
02095 connection->Unlock();
02096 }
02097 }
02098
02099 if (!irq.HasOptionalField(H225_InfoRequest::e_replyAddress))
02100 return WritePDU(response);
02101
02102 H323TransportAddress replyAddress = irq.m_replyAddress;
02103 if (replyAddress.IsEmpty())
02104 return FALSE;
02105
02106 H323TransportAddress oldAddress = transport->GetRemoteAddress();
02107
02108 BOOL ok = transport->ConnectTo(replyAddress) && WritePDU(response);
02109
02110 transport->ConnectTo(oldAddress);
02111
02112 return ok;
02113 }
02114
02115 #ifdef H323_H248
02116
02117 BOOL H323Gatekeeper::OnReceiveServiceControlIndication(const H225_ServiceControlIndication & sci)
02118 {
02119 if (!H225_RAS::OnReceiveServiceControlIndication(sci))
02120 return FALSE;
02121
02122 H323Connection * connection = NULL;
02123
02124 if (sci.HasOptionalField(H225_ServiceControlIndication::e_callSpecific)) {
02125 OpalGloballyUniqueID id = sci.m_callSpecific.m_callIdentifier.m_guid;
02126 if (id.IsNULL())
02127 id = sci.m_callSpecific.m_conferenceID;
02128 connection = endpoint.FindConnectionWithLock(id.AsString());
02129 }
02130
02131 OnServiceControlSessions(sci.m_serviceControl, connection);
02132
02133
02134 H323RasPDU response(authenticators);
02135 response.BuildServiceControlResponse(sci.m_requestSeqNum);
02136 return WritePDU(response);
02137 }
02138
02139
02140 void H323Gatekeeper::OnServiceControlSessions(const H225_ArrayOf_ServiceControlSession & serviceControl,
02141 H323Connection * connection)
02142 {
02143 for (PINDEX i = 0; i < serviceControl.GetSize(); i++) {
02144 H225_ServiceControlSession & pdu = serviceControl[i];
02145
02146 H323ServiceControlSession * session = NULL;
02147 unsigned sessionId = pdu.m_sessionId;
02148
02149 if (serviceControlSessions.Contains(sessionId)) {
02150 session = &serviceControlSessions[sessionId];
02151 if (pdu.HasOptionalField(H225_ServiceControlSession::e_contents)) {
02152 if (!session->OnReceivedPDU(pdu.m_contents)) {
02153 PTRACE(2, "SvcCtrl\tService control for session has changed!");
02154 session = NULL;
02155 }
02156 }
02157 }
02158
02159 if (session == NULL && pdu.HasOptionalField(H225_ServiceControlSession::e_contents)) {
02160 session = endpoint.CreateServiceControlSession(pdu.m_contents);
02161 serviceControlSessions.SetAt(sessionId, session);
02162 }
02163
02164 if (session != NULL)
02165 endpoint.OnServiceControlSession(pdu.m_reason.GetTag(),sessionId, *session, connection);
02166 }
02167 }
02168
02169 #endif // H323_H248
02170
02171
02172 void H323Gatekeeper::SetPassword(const PString & password,
02173 const PString & username)
02174 {
02175 localId = username;
02176 if (localId.IsEmpty())
02177 localId = endpoint.GetLocalUserName();
02178
02179 for (PINDEX i = 0; i < authenticators.GetSize(); i++) {
02180 authenticators[i].SetLocalId(localId);
02181 authenticators[i].SetPassword(password);
02182 }
02183 }
02184
02185
02186 void H323Gatekeeper::MonitorMain(PThread &, INT)
02187 {
02188 PTRACE(3, "RAS\tBackground thread started");
02189
02190 for (;;) {
02191 monitorTickle.Wait();
02192 if (monitorStop)
02193 break;
02194
02195 if (reregisterNow ||
02196 (!timeToLive.IsRunning() && timeToLive.GetResetTime() > 0)) {
02197 RegistrationTimeToLive();
02198 timeToLive.Reset();
02199 }
02200
02201 if (!infoRequestRate.IsRunning() && infoRequestRate.GetResetTime() > 0) {
02202 InfoRequestResponse();
02203 infoRequestRate.Reset();
02204 }
02205 }
02206
02207 PTRACE(3, "RAS\tBackground thread ended");
02208 }
02209
02210
02211 void H323Gatekeeper::TickleMonitor(PTimer &, INT)
02212 {
02213 monitorTickle.Signal();
02214 }
02215
02216
02217 void H323Gatekeeper::SetAlternates(const H225_ArrayOf_AlternateGK & alts, BOOL permanent)
02218 {
02219 PINDEX i;
02220
02221 if (!alternatePermanent) {
02222
02223 for (i = 0; i < alternates.GetSize(); i++) {
02224 if (transport->GetRemoteAddress().IsEquivalent(alternates[i].rasAddress) &&
02225 gatekeeperIdentifier == alternates[i].gatekeeperIdentifier)
02226 return;
02227 }
02228 }
02229
02230 alternates.RemoveAll();
02231
02232 if (assignedGK != NULL)
02233 alternates.Append(assignedGK);
02234
02235 for (i = 0; i < alts.GetSize(); i++) {
02236 AlternateInfo * alt = new AlternateInfo(alts[i]);
02237 if (alt->rasAddress.IsEmpty())
02238 delete alt;
02239 else
02240 alternates.Append(alt);
02241 }
02242
02243 alternatePermanent = permanent;
02244
02245 PTRACE(3, "RAS\tSet alternate gatekeepers:\n"
02246 << setfill('\n') << alternates << setfill(' '));
02247 }
02248
02249 void H323Gatekeeper::SetAssignedGatekeeper(const H225_AlternateGK & gk)
02250 {
02251 assignedGK = new AlternateInfo(gk);
02252 }
02253
02254 BOOL H323Gatekeeper::GetAssignedGatekeeper(H225_AlternateGK & gk)
02255 {
02256 if (assignedGK == NULL)
02257 return FALSE;
02258
02259 gk = assignedGK->GetAlternate();
02260 return TRUE;
02261 }
02262
02263
02264 BOOL H323Gatekeeper::MakeRequestWithReregister(Request & request, unsigned unregisteredTag)
02265 {
02266 if (MakeRequest(request))
02267 return TRUE;
02268
02269 if (request.responseResult == Request::RejectReceived &&
02270 request.rejectReason != unregisteredTag)
02271 return FALSE;
02272
02273 PTRACE(2, "RAS\tEndpoint has become unregistered from gatekeeper " << gatekeeperIdentifier);
02274
02275
02276 switch (request.responseResult) {
02277 case Request::NoResponseReceived :
02278 registrationFailReason = TransportError;
02279 break;
02280
02281 case Request::BadCryptoTokens :
02282 registrationFailReason = SecurityDenied;
02283 break;
02284
02285 default :
02286 registrationFailReason = GatekeeperLostRegistration;
02287 }
02288
02289
02290 if (!autoReregister)
02291 return FALSE;
02292
02293 reregisterNow = TRUE;
02294 monitorTickle.Signal();
02295 return FALSE;
02296 }
02297
02298
02299 void H323Gatekeeper::Connect(const H323TransportAddress & address,
02300 const PString & gkid)
02301 {
02302 if (transport == NULL)
02303 transport = new H323TransportUDP(endpoint, PIPSocket::GetDefaultIpAny());
02304
02305 transport->SetRemoteAddress(address);
02306 transport->Connect();
02307 gatekeeperIdentifier = gkid;
02308 }
02309
02310
02311 BOOL H323Gatekeeper::MakeRequest(Request & request)
02312 {
02313 if (PAssertNULL(transport) == NULL)
02314 return FALSE;
02315
02316
02317 requestMutex.Wait();
02318
02319 if (request.requestPDU.GetAuthenticators().IsEmpty())
02320 request.requestPDU.SetAuthenticators(authenticators);
02321
02322
02323
02324
02325
02326 H323TransportAddress tempAddr = transport->GetRemoteAddress();
02327 PString tempIdentifier = gatekeeperIdentifier;
02328
02329 PINDEX alt = 0;
02330 for (;;) {
02331 if (H225_RAS::MakeRequest(request)) {
02332 if (!alternatePermanent &&
02333 (transport->GetRemoteAddress() != tempAddr ||
02334 gatekeeperIdentifier != tempIdentifier))
02335 Connect(tempAddr, tempIdentifier);
02336 requestMutex.Signal();
02337 return TRUE;
02338 }
02339
02340 if (request.responseResult != Request::NoResponseReceived &&
02341 request.responseResult != Request::TryAlternate) {
02342
02343 requestMutex.Signal();
02344 return FALSE;
02345 }
02346
02347 AlternateInfo * altInfo;
02348 PIPSocket::Address localAddress;
02349 WORD localPort;
02350 do {
02351 if (alt >= alternates.GetSize()) {
02352 if (!alternatePermanent)
02353 Connect(tempAddr,tempIdentifier);
02354 requestMutex.Signal();
02355 return FALSE;
02356 }
02357
02358 altInfo = &alternates[alt++];
02359 transport->GetLocalAddress().GetIpAndPort(localAddress,localPort);
02360 transport->CleanUpOnTermination();
02361 delete transport;
02362
02363 transport = new H323TransportUDP(endpoint,localAddress,localPort);
02364 transport->SetRemoteAddress (altInfo->rasAddress);
02365 transport->Connect();
02366 gatekeeperIdentifier = altInfo->gatekeeperIdentifier;
02367 StartChannel();
02368 } while (altInfo->registrationState == AlternateInfo::RegistrationFailed);
02369
02370 if (altInfo->registrationState == AlternateInfo::NeedToRegister) {
02371 altInfo->registrationState = AlternateInfo::RegistrationFailed;
02372 registrationFailReason = TransportError;
02373 discoveryComplete = FALSE;
02374 H323RasPDU pdu;
02375 Request req(SetupGatekeeperRequest(pdu), pdu);
02376
02377 if (H225_RAS::MakeRequest(req)) {
02378 requestMutex.Signal();
02379 if (RegistrationRequest(autoReregister)) {
02380 altInfo->registrationState = AlternateInfo::IsRegistered;
02381
02382 if (request.requestPDU.GetChoice().GetTag() == H225_RasMessage::e_registrationRequest) {
02383 if (!alternatePermanent)
02384 Connect(tempAddr,tempIdentifier);
02385 return TRUE;
02386 }
02387 }
02388 requestMutex.Wait();
02389 }
02390 }
02391 }
02392 }
02393
02394
02395 H323Gatekeeper::AlternateInfo::AlternateInfo(const H225_AlternateGK & alt)
02396 : rasAddress(alt.m_rasAddress),
02397 gatekeeperIdentifier(alt.m_gatekeeperIdentifier.GetValue()),
02398 priority(alt.m_priority)
02399 {
02400 registrationState = alt.m_needToRegister ? NeedToRegister : NoRegistrationNeeded;
02401 }
02402
02403
02404 H323Gatekeeper::AlternateInfo::~AlternateInfo ()
02405 {
02406
02407 }
02408
02409
02410 PObject::Comparison H323Gatekeeper::AlternateInfo::Compare(const PObject & obj)
02411 {
02412 PAssert(PIsDescendant(&obj, H323Gatekeeper), PInvalidCast);
02413 unsigned otherPriority = ((const AlternateInfo & )obj).priority;
02414 if (priority < otherPriority)
02415 return LessThan;
02416 if (priority > otherPriority)
02417 return GreaterThan;
02418 return EqualTo;
02419 }
02420
02421 H225_AlternateGK H323Gatekeeper::AlternateInfo::GetAlternate()
02422 {
02423 H225_AlternateGK gk;
02424 rasAddress.SetPDU(gk.m_rasAddress);
02425 gk.m_gatekeeperIdentifier = gatekeeperIdentifier;
02426 gk.m_priority = priority;
02427 gk.m_needToRegister = registrationState;
02428
02429 return gk;
02430 }
02431
02432
02433 void H323Gatekeeper::AlternateInfo::PrintOn(ostream & strm) const
02434 {
02435 if (!gatekeeperIdentifier)
02436 strm << gatekeeperIdentifier << '@';
02437
02438 strm << rasAddress;
02439
02440 if (priority > 0)
02441 strm << ";priority=" << priority;
02442 }
02443
02444 BOOL H323Gatekeeper::OnSendFeatureSet(unsigned pduType, H225_FeatureSet & feats) const
02445 {
02446 #ifdef H323_H460
02447 return features.SendFeature(pduType, feats);
02448 #else
02449 return endpoint.OnSendFeatureSet(pduType, feats);
02450 #endif
02451 }
02452
02453 void H323Gatekeeper::OnReceiveFeatureSet(unsigned pduType, const H225_FeatureSet & feats) const
02454 {
02455 #ifdef H323_H460
02456 features.ReceiveFeature(pduType, feats);
02457 #else
02458 endpoint.OnReceiveFeatureSet(pduType, feats);
02459 #endif
02460 }
02461