00001 /* 00002 * gkclient.cxx 00003 * 00004 * Gatekeeper client protocol handler 00005 * 00006 * Open H323 Library 00007 * 00008 * Copyright (c) 1999-2000 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Open H323 Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Portions of this code were written with the assisance of funding from 00025 * iFace In, http://www.iface.com 00026 * 00027 * Contributor(s): ______________________________________. 00028 * 00029 * $Log: gkclient.cxx,v $ 00030 * Revision 1.2 2007/10/16 17:02:47 shorne 00031 * Fix for H.235.1 on full reregistration 00032 * 00033 * Revision 1.1 2007/08/06 20:51:04 shorne 00034 * First commit of h323plus 00035 * 00036 * Revision 1.165.2.5 2007/07/23 21:47:11 shorne 00037 * Added QoS GK Reporting 00038 * 00039 * Revision 1.165.2.4 2007/07/19 20:05:56 shorne 00040 * Changed Terminal Aliases to be only sent on full registration 00041 * 00042 * Revision 1.165.2.3 2007/05/23 06:59:36 shorne 00043 * Added Assigned Alias/Gatekeeper 00044 * 00045 * Revision 1.165.2.2 2007/04/19 12:16:16 shorne 00046 * added ability to detect if no nat 00047 * 00048 * Revision 1.165.2.1 2006/12/23 19:08:02 shorne 00049 * Plugin video codecs & sundry 00050 * 00051 * Revision 1.165 2006/07/23 23:27:55 shorne 00052 * supportsAssignedGK made optional field in RRQ & GRQ for backwards interoperability 00053 * 00054 * Revision 1.164 2006/07/21 16:29:13 csoutheren 00055 * Initialise mandatory extension elements in GRQ and RRQ for H.225 V6 00056 * 00057 * Revision 1.163 2006/06/30 05:26:43 csoutheren 00058 * Applied 1509255 - Checking whether SetSize succeeds in GkClient 00059 * Thanks to Borko Jandras 00060 * 00061 * Revision 1.162 2006/06/09 06:30:12 csoutheren 00062 * Remove compile warning and errors with gcc 00063 * 00064 * Revision 1.161 2006/05/30 11:14:56 hfriederich 00065 * Switch from DISABLE_H460 to H323_H460 00066 * 00067 * Revision 1.160 2006/05/29 02:31:45 shorne 00068 * H460 functions now get called 00069 * 00070 * Revision 1.159 2006/05/18 17:15:54 shorne 00071 * Added H460 Support 00072 * 00073 * Revision 1.158 2006/05/16 11:39:39 shorne 00074 * call linkage support 00075 * 00076 * Revision 1.157 2006/03/07 10:37:46 csoutheren 00077 * Add ability to disable GRQ on GK registration 00078 * 00079 * Revision 1.156 2005/11/21 20:52:35 shorne 00080 * Added GnuGK Nat detection support 00081 * 00082 * Revision 1.155 2005/01/16 20:39:44 csoutheren 00083 * Fixed problem with IPv6 INADDR_ANY 00084 * 00085 * Revision 1.154 2005/01/03 06:25:54 csoutheren 00086 * Added extensive support for disabling code modules at compile time 00087 * 00088 * Revision 1.153 2004/11/20 22:00:10 csoutheren 00089 * Check address from RequestLocation due to stupid gatekeepers 00090 * 00091 * Revision 1.152 2004/09/07 23:51:46 rjongbloed 00092 * Fixed MSVC6 warning 00093 * 00094 * Revision 1.151 2004/09/03 01:06:09 csoutheren 00095 * Added initial hooks for H.460 GEF 00096 * Thanks to Simon Horne and ISVO (Asia) Pte Ltd. for this contribution 00097 * 00098 * Revision 1.150 2004/06/15 03:30:00 csoutheren 00099 * Added OnSendARQ to allow access to the ARQ message before sent by connection 00100 * 00101 * Revision 1.149 2004/04/03 08:28:06 csoutheren 00102 * Remove pseudo-RTTI and replaced with real RTTI 00103 * 00104 * Revision 1.148 2004/01/17 18:20:15 csoutheren 00105 * No longer force re-register on completion of LRQ 00106 * 00107 * Revision 1.147 2003/12/29 04:59:25 csoutheren 00108 * Added callbacks on H323EndPoint when gatekeeper discovery succeeds or fails 00109 * 00110 * Revision 1.146 2003/12/28 00:06:34 csoutheren 00111 * Added callbacks on H323EndPoint when gatekeeper registration succeeds or fails 00112 * 00113 * Revision 1.145 2003/05/01 05:04:00 robertj 00114 * Fixed inclusion of 127.0.0.1 into listener lists when no needed. 00115 * 00116 * Revision 1.144 2003/04/30 07:25:32 robertj 00117 * Fixed setting of remote ID in alternate credentials. 00118 * 00119 * Revision 1.143 2003/04/30 00:28:54 robertj 00120 * Redesigned the alternate credentials in ARQ system as old implementation 00121 * was fraught with concurrency issues, most importantly it can cause false 00122 * detection of replay attacks taking out an endpoint completely. 00123 * 00124 * Revision 1.142 2003/04/10 09:44:31 robertj 00125 * Added associated transport to new GetInterfaceAddresses() function so 00126 * interfaces can be ordered according to active transport links. Improves 00127 * interoperability. 00128 * Replaced old listener GetTransportPDU() with GetInterfaceAddresses() 00129 * and H323SetTransportAddresses() functions. 00130 * 00131 * Revision 1.141 2003/04/09 03:08:10 robertj 00132 * Fixed race condition in shutting down transactor (pure virtual call) 00133 * 00134 * Revision 1.140 2003/03/26 00:46:28 robertj 00135 * Had another go at making H323Transactor being able to be created 00136 * without having a listener running. 00137 * 00138 * Revision 1.139 2003/03/20 01:51:11 robertj 00139 * More abstraction of H.225 RAS and H.501 protocols transaction handling. 00140 * 00141 * Revision 1.138 2003/02/21 05:25:45 craigs 00142 * Abstracted out underlying transports for use with peerelements 00143 * 00144 * Revision 1.137 2003/02/12 23:59:25 robertj 00145 * Fixed adding missing endpoint identifer in SETUP packet when gatekeeper 00146 * routed, pointed out by Stefan Klein 00147 * Also fixed correct rutrn of gk routing in IRR packet. 00148 * 00149 * Revision 1.136 2003/02/11 04:46:37 robertj 00150 * Fixed keep alive RRQ being rejected with full registration required 00151 * reason actually doing a full registration! 00152 * 00153 * Revision 1.135 2003/02/10 01:51:50 robertj 00154 * Fixed bad tokens causing an apparent "transport error", now correctly 00155 * indicates a security error. 00156 * 00157 * Revision 1.134 2003/02/07 06:38:47 robertj 00158 * Changed registration state to an enum so can determine why the RRQ failed. 00159 * 00160 * Revision 1.133 2003/02/04 07:04:45 robertj 00161 * Prevent multiple calls to Connect() if did not change the gk. 00162 * 00163 * Revision 1.132 2003/02/01 13:31:21 robertj 00164 * Changes to support CAT authentication in RAS. 00165 * 00166 * Revision 1.131 2003/01/11 05:04:03 robertj 00167 * Added checks for valid URQ packet, thanks Chih-Wei Huang 00168 * 00169 * Revision 1.130 2003/01/09 04:45:04 robertj 00170 * Fixed problem where if gets GRJ which does not have an alternate gatekeeper 00171 * the system gets into an infinite loop, pointed out by Vladimir Toncar 00172 * 00173 * Revision 1.129 2003/01/06 07:09:43 robertj 00174 * Further fixes for alternate gatekeeper, thanks Kevin Bouchard 00175 * 00176 * Revision 1.128 2002/12/23 22:47:53 robertj 00177 * Changed gatekeeper discovery so an GRJ does not indicate "discovered". 00178 * Added trace output of alternate gatekeepers list. 00179 * Fixed receiving GRJ with alternate gatekeepers to immediately do discover 00180 * and registration on the alternate. 00181 * 00182 * Revision 1.127 2002/12/19 23:52:53 robertj 00183 * Fixed probelm with registering with alternate gk, thanks Kevin Bouchard 00184 * 00185 * Revision 1.126 2002/12/10 23:39:03 robertj 00186 * Added some extra tracing. 00187 * 00188 * Revision 1.125 2002/11/28 04:41:48 robertj 00189 * Added support for RAS ServiceControlIndication command. 00190 * 00191 * Revision 1.124 2002/11/27 06:54:56 robertj 00192 * Added Service Control Session management as per Annex K/H.323 via RAS 00193 * only at this stage. 00194 * Added H.248 ASN and very primitive infrastructure for linking into the 00195 * Service Control Session management system. 00196 * Added basic infrastructure for Annex K/H.323 HTTP transport system. 00197 * Added Call Credit Service Control to display account balances. 00198 * 00199 * Revision 1.123 2002/11/22 07:16:14 robertj 00200 * Changed ARQ to include all local aliases for connection. 00201 * 00202 * Revision 1.122 2002/11/21 07:29:15 robertj 00203 * Fixed GNU warning 00204 * 00205 * Revision 1.121 2002/11/21 07:21:49 robertj 00206 * Improvements to alternate gatekeeper client code, thanks Kevin Bouchard 00207 * 00208 * Revision 1.120 2002/11/12 03:13:24 robertj 00209 * Removed redundent code. 00210 * 00211 * Revision 1.119 2002/11/10 08:10:43 robertj 00212 * Moved constants for "well known" ports to better place (OPAL change). 00213 * 00214 * Revision 1.118 2002/11/01 03:48:18 robertj 00215 * Fixed previous two hacks!! Neither of which would have worked. 00216 * 00217 * Revision 1.117 2002/10/31 23:31:41 dereks 00218 * Fix for previous quick hack. Thanks Damien Sandras. 00219 * 00220 * Revision 1.116 2002/10/31 21:40:28 dereks 00221 * Quick (and temporary) hack to enable compilation on redhat 8.0 boxes. 00222 * 00223 * Revision 1.115 2002/09/19 23:19:25 robertj 00224 * Fixed setting of info request rate, broken in a previous patch 00225 * 00226 * Revision 1.114 2002/09/18 06:58:32 robertj 00227 * Fixed setting of IRR frequency, an RCF could reset timer so it did not time 00228 * out correctly and send IRR in time causing problems with gatekeeper. 00229 * 00230 * Revision 1.113 2002/09/09 23:59:59 robertj 00231 * Fixed incorrect inserting of UUIE pdu's into IRR, thanks Ravelli Rossano 00232 * 00233 * Revision 1.112 2002/08/29 07:02:19 robertj 00234 * Allowed network latency deadband in unsolicited IRR response time. 00235 * 00236 * Revision 1.111 2002/08/28 00:07:02 robertj 00237 * Added supportsAltGK capability flag in GRQ & RRQ. 00238 * 00239 * Revision 1.110 2002/08/15 09:38:55 robertj 00240 * Added more logging for when endpoint becomes unregistered. 00241 * 00242 * Revision 1.109 2002/08/15 04:12:54 robertj 00243 * Fixed correct status of isRegistered flag on various reject/errors. 00244 * 00245 * Revision 1.108 2002/08/12 05:38:24 robertj 00246 * Changes to the RAS subsystem to support ability to make requests to client 00247 * from gkserver without causing bottlenecks and race conditions. 00248 * 00249 * Revision 1.107 2002/08/11 23:30:36 robertj 00250 * Fixed typo in previous patch. 00251 * 00252 * Revision 1.106 2002/08/11 23:24:24 robertj 00253 * Fixed problem with retrying ARQ after getting error saying are not 00254 * registered and reregistering, needed new sequence number. 00255 * Fixed return of correct error in ARQ response when is a transport error 00256 * rather than a reject reason from ARJ. 00257 * 00258 * Revision 1.105 2002/08/05 10:03:47 robertj 00259 * Cosmetic changes to normalise the usage of pragma interface/implementation. 00260 * 00261 * Revision 1.104 2002/08/05 05:17:41 robertj 00262 * Fairly major modifications to support different authentication credentials 00263 * in ARQ to the logged in ones on RRQ. For both client and server. 00264 * Various other H.235 authentication bugs and anomalies fixed on the way. 00265 * 00266 * Revision 1.103 2002/07/19 10:20:03 robertj 00267 * Fixed bug of missing test for IRR frequency in RCF, thanks Thien Nguyen 00268 * 00269 * Revision 1.102 2002/07/18 03:03:19 robertj 00270 * Fixed bug with continually doing lightweight RRQ if no timeToLive present 00271 * and it should not be doing it at all, ditto for unsolicited IRR. 00272 * 00273 * Revision 1.101 2002/07/17 00:04:10 robertj 00274 * Fixed missing initialisation of alternat gk pointer to NULL, thanks Kevin Bouchard 00275 * 00276 * Revision 1.100 2002/07/16 13:19:13 robertj 00277 * Minor optimisation of unsolicited IRR when no calls active. 00278 * 00279 * Revision 1.99 2002/07/16 11:06:27 robertj 00280 * Added more alternate gatekeeper implementation, thanks Kevin Bouchard 00281 * 00282 * Revision 1.98 2002/07/11 09:34:32 robertj 00283 * Fixed minor compliance to letter of specification. 00284 * 00285 * Revision 1.97 2002/07/11 01:34:37 robertj 00286 * Temporary fix for IRR frequency provided in ACF 00287 * 00288 * Revision 1.96 2002/07/07 02:08:53 robertj 00289 * Fixed missing originator field in IRR perCallInfo, thanks Ravelli Rossano 00290 * 00291 * Revision 1.95 2002/06/28 03:34:28 robertj 00292 * Fixed issues with address translation on gatekeeper RAS channel. 00293 * 00294 * Revision 1.94 2002/06/26 03:47:49 robertj 00295 * Added support for alternate gatekeepers. 00296 * 00297 * Revision 1.93 2002/06/26 00:50:12 robertj 00298 * Added other error code in ARJ that indicates we should reregister. 00299 * 00300 * Revision 1.92 2002/06/05 09:20:07 robertj 00301 * Added IRQ redirect of IRR to different address, thanks "thsuk". 00302 * 00303 * Revision 1.91 2002/05/29 00:03:19 robertj 00304 * Fixed unsolicited IRR support in gk client and server, 00305 * including support for IACK and INAK. 00306 * 00307 * Revision 1.90 2002/05/17 04:01:53 robertj 00308 * Fixed problems with H.235 authentication on RAS for server and client. 00309 * Added support for unsolicited IRR transmission in background (heartbeat). 00310 * 00311 * Revision 1.89 2002/05/09 05:43:44 robertj 00312 * Added reattempt of full RRQ if get fullRegistrationRequired RRJ. 00313 * 00314 * Revision 1.88 2002/05/01 06:39:41 robertj 00315 * Fixed incorrect setting of srcCallSignalAddress in ARQ for outgoing call as 00316 * putting in incorrect data is worse than not putting anything in at all! So 00317 * unless the correct data is available it is now left out. 00318 * 00319 * Revision 1.87 2002/03/20 02:12:49 robertj 00320 * Added missing return value for number of endpoints returned in ACF 00321 * 00322 * Revision 1.86 2002/03/19 05:17:25 robertj 00323 * Normalised ACF destExtraCallIInfo to be same as other parameters. 00324 * Added ability to get multiple endpoint addresses and tokens from ACF. 00325 * 00326 * Revision 1.85 2002/03/01 04:06:44 robertj 00327 * Fixed autoreregister on ARQ failing due to unregistered endpoint. 00328 * 00329 * Revision 1.84 2002/02/11 04:25:57 robertj 00330 * Added ability to automatically reregister if do an ARQ and are told are not 00331 * registered. Can occur if gk is restarted and is faster than waiting for TTL.. 00332 * 00333 * Revision 1.83 2002/01/13 23:58:48 robertj 00334 * Added ability to set destination extra call info in ARQ 00335 * Filled in destinationInfo in ARQ when answering call. 00336 * Allowed application to override srcInfo in ARQ on outgoing call by 00337 * changing localPartyName. 00338 * Added better end call codes for some ARJ reasons. 00339 * Thanks Ben Madsen of Norwood Systems. 00340 * 00341 * Revision 1.82 2001/12/15 10:10:48 robertj 00342 * GCC compatibility 00343 * 00344 * Revision 1.81 2001/12/15 08:36:49 robertj 00345 * Added previous call times to all the other PDU's it is supposed to be in! 00346 * 00347 * Revision 1.80 2001/12/15 08:09:21 robertj 00348 * Added alerting, connect and end of call times to be sent to RAS server. 00349 * 00350 * Revision 1.79 2001/12/14 06:41:36 robertj 00351 * Added call end reason codes in DisengageRequest for GK server use. 00352 * 00353 * Revision 1.78 2001/12/13 11:00:13 robertj 00354 * Changed search for access token in ACF to be able to look for two OID's. 00355 * 00356 * Revision 1.77 2001/12/06 06:44:42 robertj 00357 * Removed "Win32 SSL xxx" build configurations in favour of system 00358 * environment variables to select optional libraries. 00359 * 00360 * Revision 1.76 2001/10/12 04:14:31 robertj 00361 * Changed gk unregister so only way it doe not actually unregister is if 00362 * get URJ with reason code callInProgress, thanks Chris Purvis. 00363 * 00364 * Revision 1.75 2001/10/09 08:04:59 robertj 00365 * Fixed unregistration so still unregisters if gk goes offline, thanks Chris Purvis 00366 * 00367 * Revision 1.74 2001/10/08 01:37:42 robertj 00368 * Fixed uninitialised variable for ARQ authentication override. 00369 * 00370 * Revision 1.73 2001/09/26 07:03:08 robertj 00371 * Added needed mutex for SeparateAuthenticationInARQ mode, thanks Nick Hoath 00372 * 00373 * Revision 1.72 2001/09/18 10:36:57 robertj 00374 * Allowed multiple overlapping requests in RAS channel. 00375 * 00376 * Revision 1.71 2001/09/13 03:21:16 robertj 00377 * Added ability to override authentication credentials for ARQ, thanks Nick Hoath 00378 * 00379 * Revision 1.70 2001/09/13 01:15:20 robertj 00380 * Added flag to H235Authenticator to determine if gkid and epid is to be 00381 * automatically set as the crypto token remote id and local id. 00382 * 00383 * Revision 1.69 2001/09/13 00:32:24 robertj 00384 * Added missing gkid in ARQ, thanks Nick Hoath 00385 * 00386 * Revision 1.68 2001/09/12 07:48:05 robertj 00387 * Fixed various problems with tracing. 00388 * 00389 * Revision 1.67 2001/09/12 06:58:00 robertj 00390 * Added support for iNow Access Token from gk, thanks Nick Hoath 00391 * 00392 * Revision 1.66 2001/09/12 06:04:38 robertj 00393 * Added support for sending UUIE's to gk on request, thanks Nick Hoath 00394 * 00395 * Revision 1.65 2001/09/05 01:16:32 robertj 00396 * Added overloaded AdmissionRequest for backward compatibility. 00397 * 00398 * Revision 1.64 2001/08/14 04:26:46 robertj 00399 * Completed the Cisco compatible MD5 authentications, thanks Wolfgang Platzer. 00400 * 00401 * Revision 1.63 2001/08/13 01:27:03 robertj 00402 * Changed GK admission so can return multiple aliases to be used in 00403 * setup packet, thanks Nick Hoath. 00404 * 00405 * Revision 1.62 2001/08/13 00:22:14 robertj 00406 * Allowed for received DRQ not having call ID (eg v1 gk), uses conference ID 00407 * 00408 * Revision 1.61 2001/08/10 11:03:52 robertj 00409 * Major changes to H.235 support in RAS to support server. 00410 * 00411 * Revision 1.60 2001/08/06 07:44:55 robertj 00412 * Fixed problems with building without SSL 00413 * 00414 * Revision 1.59 2001/08/06 03:18:38 robertj 00415 * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files. 00416 * Improved access to H.235 secure RAS functionality. 00417 * Changes to H.323 secure RAS contexts to help use with gk server. 00418 * 00419 * Revision 1.58 2001/08/02 04:30:43 robertj 00420 * Added ability for AdmissionRequest to alter destination alias used in 00421 * the outgoing call. Thanks Ben Madsen & Graeme Reid. 00422 * 00423 * Revision 1.57 2001/06/22 00:21:10 robertj 00424 * Fixed bug in H.225 RAS protocol with 16 versus 32 bit sequence numbers. 00425 * 00426 * Revision 1.56 2001/06/18 23:35:01 robertj 00427 * Removed condition that prevented aliases on non-terminal endpoints. 00428 * 00429 * Revision 1.55 2001/06/18 06:23:50 robertj 00430 * Split raw H.225 RAS protocol out of gatekeeper client class. 00431 * 00432 * Revision 1.54 2001/05/17 03:29:13 robertj 00433 * Fixed missing replyAddress in LRQ, thanks Alexander Smirnov. 00434 * Added some extra optional fields to LRQ. 00435 * 00436 * Revision 1.53 2001/04/19 08:03:21 robertj 00437 * Fixed scale on RIp delay, is milliseconds! 00438 * 00439 * Revision 1.52 2001/04/13 07:44:20 robertj 00440 * Fixed setting isRegistered flag to false when get RRJ 00441 * 00442 * Revision 1.51 2001/04/05 03:39:43 robertj 00443 * Fixed deadlock if tried to do discovery in time to live timeout. 00444 * 00445 * Revision 1.50 2001/03/28 07:13:06 robertj 00446 * Changed RAS thread interlock to allow for what should not happen, the 00447 * syncpoint being signalled before receiving any packets. 00448 * 00449 * Revision 1.49 2001/03/27 02:19:22 robertj 00450 * Changed to send gk a GRQ if it gives a discoveryRequired error on RRQ. 00451 * Fixed BIG condition in use of sequence numbers. 00452 * 00453 * Revision 1.48 2001/03/26 05:06:03 robertj 00454 * Added code to do full registration if RRJ indicates discovery to be redone. 00455 * 00456 * Revision 1.47 2001/03/24 00:51:41 robertj 00457 * Added retry every minute of time to live registration if fails. 00458 * 00459 * Revision 1.46 2001/03/23 01:47:49 robertj 00460 * Improved debug trace message on RAS packet retry. 00461 * 00462 * Revision 1.45 2001/03/23 01:19:25 robertj 00463 * Fixed usage of secure RAS in GRQ, should not do for that one PDU. 00464 * 00465 * Revision 1.44 2001/03/21 04:52:42 robertj 00466 * Added H.235 security to gatekeepers, thanks Fürbass Franz! 00467 * 00468 * Revision 1.43 2001/03/19 23:32:30 robertj 00469 * Fixed problem with auto-reregister doing so in the RAS receive thread. 00470 * 00471 * Revision 1.42 2001/03/19 05:50:52 robertj 00472 * Fixed trace display of timeout value. 00473 * 00474 * Revision 1.41 2001/03/18 22:21:29 robertj 00475 * Fixed GNU C++ problem. 00476 * 00477 * Revision 1.40 2001/03/17 00:05:52 robertj 00478 * Fixed problems with Gatekeeper RIP handling. 00479 * 00480 * Revision 1.39 2001/03/16 06:46:21 robertj 00481 * Added ability to set endpoints desired time to live on a gatekeeper. 00482 * 00483 * Revision 1.38 2001/03/15 00:25:58 robertj 00484 * Fixed bug in receiving RIP packet, did not restart timeout. 00485 * 00486 * Revision 1.37 2001/03/09 02:55:53 robertj 00487 * Fixed bug in RAS IRR, optional field not being included, thanks Erik Larsson. 00488 * 00489 * Revision 1.36 2001/03/02 06:59:59 robertj 00490 * Enhanced the globally unique identifier class. 00491 * 00492 * Revision 1.35 2001/02/28 00:20:16 robertj 00493 * Added DiscoverByNameAndAddress() function, thanks Chris Purvis. 00494 * 00495 * Revision 1.34 2001/02/18 22:33:47 robertj 00496 * Added better handling of URJ, thanks Chris Purvis. 00497 * 00498 * Revision 1.33 2001/02/09 05:13:55 craigs 00499 * Added pragma implementation to (hopefully) reduce the executable image size 00500 * under Linux 00501 * 00502 * Revision 1.32 2001/01/25 01:44:26 robertj 00503 * Reversed order of changing alias list to avoid assert if delete all aliases. 00504 * 00505 * Revision 1.31 2000/11/01 03:30:27 robertj 00506 * Changed gatekeeper registration time to live to update in slightly less than the 00507 * time to live time. Allows for system/network latency. Thanks Laurent PELLETIER. 00508 * 00509 * Revision 1.30 2000/09/25 06:48:11 robertj 00510 * Removed use of alias if there is no alias present, ie only have transport address. 00511 * 00512 * Revision 1.29 2000/09/01 02:12:37 robertj 00513 * Fixed problem when multiple GK's on LAN, only discovered first one. 00514 * Added ability to select a gatekeeper on LAN via it's identifier name. 00515 * 00516 * Revision 1.28 2000/07/15 09:54:21 robertj 00517 * Fixed problem with having empty or unusable assigned aliases. 00518 * 00519 * Revision 1.27 2000/07/11 19:26:39 robertj 00520 * Fixed problem with endpoint identifiers from some gatekeepers not being a string, just binary info. 00521 * 00522 * Revision 1.26 2000/06/20 03:18:04 robertj 00523 * Added function to get name of gatekeeper, subtle difference from getting identifier. 00524 * 00525 * Revision 1.25 2000/05/09 12:14:32 robertj 00526 * Added adjustment of endpoints alias list as approved by gatekeeper. 00527 * 00528 * Revision 1.24 2000/05/09 08:52:50 robertj 00529 * Added support for preGrantedARQ fields on registration. 00530 * 00531 * Revision 1.23 2000/05/04 10:43:54 robertj 00532 * Fixed problem with still trying to RRQ if got a GRJ. 00533 * 00534 * Revision 1.22 2000/05/02 04:32:26 robertj 00535 * Fixed copyright notice comment. 00536 * 00537 * Revision 1.21 2000/04/27 02:52:58 robertj 00538 * Added keepAlive field to RRQ if already registered, 00539 * 00540 * Revision 1.20 2000/04/12 21:22:16 robertj 00541 * Fixed warning in No Trace mode. 00542 * 00543 * Revision 1.19 2000/04/11 04:00:55 robertj 00544 * Filled in destCallSignallingAddress if specified by caller, used for gateway permissions. 00545 * 00546 * Revision 1.18 2000/04/11 03:11:12 robertj 00547 * Added ability to reject reason on gatekeeper requests. 00548 * 00549 * Revision 1.17 2000/03/29 02:14:43 robertj 00550 * Changed TerminationReason to CallEndReason to use correct telephony nomenclature. 00551 * Added CallEndReason for capability exchange failure. 00552 * 00553 * Revision 1.16 2000/03/23 02:45:28 robertj 00554 * Changed ClearAllCalls() so will wait for calls to be closed (usefull in endpoint dtors). 00555 * 00556 * Revision 1.15 2000/03/21 23:17:55 robertj 00557 * Changed GK client so does not fill in destCallSignalAddress on outgoing call. 00558 * 00559 * Revision 1.14 2000/01/28 00:56:48 robertj 00560 * Changed ACF to return destination address irrespective of callModel, thanks Chris Gindel. 00561 * 00562 * Revision 1.13 1999/12/23 23:02:35 robertj 00563 * File reorganision for separating RTP from H.323 and creation of LID for VPB support. 00564 * 00565 * Revision 1.12 1999/12/11 02:20:58 robertj 00566 * Added ability to have multiple aliases on local endpoint. 00567 * 00568 * Revision 1.11 1999/12/10 01:43:25 robertj 00569 * Fixed outgoing call Admissionrequestion addresses. 00570 * 00571 * Revision 1.10 1999/12/09 21:49:18 robertj 00572 * Added reregister on unregister and time to live reregistration 00573 * 00574 * Revision 1.9 1999/11/06 05:37:45 robertj 00575 * Complete rewrite of termination of connection to avoid numerous race conditions. 00576 * 00577 * Revision 1.8 1999/10/16 03:47:48 robertj 00578 * Fixed termination of gatekeeper RAS thread problem 00579 * 00580 * Revision 1.7 1999/10/15 05:55:50 robertj 00581 * Fixed crash in responding to InfoRequest 00582 * 00583 * Revision 1.6 1999/09/23 08:48:45 robertj 00584 * Changed register request so cannot do it of have no listeners. 00585 * 00586 * Revision 1.5 1999/09/21 14:09:19 robertj 00587 * Removed warnings when no tracing enabled. 00588 * 00589 * Revision 1.4 1999/09/14 08:19:37 robertj 00590 * Fixed timeout on retry of gatekeeper discover and added more tracing. 00591 * 00592 * Revision 1.3 1999/09/14 06:52:54 robertj 00593 * Added better support for multi-homed client hosts. 00594 * 00595 * Revision 1.2 1999/09/10 02:45:31 robertj 00596 * Added missing binding of address to transport when a specific gatway is used. 00597 * 00598 * Revision 1.1 1999/08/31 12:34:18 robertj 00599 * Added gatekeeper support. 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 // Allow for an incredible amount of system/network latency 00629 static unsigned TimeoutDeadband = 5; // seconds 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 // Transport failure, retry 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 // This will force the gatekeeper to register to the assigned Gatekeeper. 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 // If discoveryComplete flag is FALSE then do lightweight reregister 00909 rrq.m_discoveryComplete = discoveryComplete; 00910 00911 // Check if the IP address might of changed since last registration (for DDNS Type registrations) 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()) { // only send terminal aliases on full registration reset localId 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 // After doing full register, do lightweight reregisters from now on 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 // If have been told by GK that we need to discover it again, set flag 00998 // for next register done by timeToLive handler to do discovery 00999 requiresDiscovery = TRUE; 01000 // Do next case 01001 01002 case H225_RegistrationRejectReason::e_fullRegistrationRequired : 01003 registrationFailReason = GatekeeperLostRegistration; 01004 // Set timer to retry registration 01005 reregisterNow = TRUE; 01006 monitorTickle.Signal(); 01007 break; 01008 01009 // Onse below here are permananent errors, so don't try again 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; // zero disables lightweight RRQ 01061 01062 // At present only support first call signal address to GK 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 // Remove the endpoint aliases that the gatekeeper did not like and add the 01085 // ones that it really wants us to be. 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 // NAT Detection with GNUGK 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))