1266e564dSmrg/****************************************************************************** 2266e564dSmrg 3266e564dSmrg 4266e564dSmrgCopyright 1993, 1998 The Open Group 5266e564dSmrg 6266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its 7266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that 8266e564dSmrgthe above copyright notice appear in all copies and that both that 9266e564dSmrgcopyright notice and this permission notice appear in supporting 10266e564dSmrgdocumentation. 11266e564dSmrg 12266e564dSmrgThe above copyright notice and this permission notice shall be included in 13266e564dSmrgall copies or substantial portions of the Software. 14266e564dSmrg 15266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21266e564dSmrg 22266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be 23266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings 24266e564dSmrgin this Software without prior written authorization from The Open Group. 25266e564dSmrg 26266e564dSmrgAuthor: Ralph Mor, X Consortium 27266e564dSmrg******************************************************************************/ 28266e564dSmrg 29266e564dSmrg#ifdef HAVE_CONFIG_H 30266e564dSmrg#include <config.h> 31266e564dSmrg#endif 32266e564dSmrg#include <X11/ICE/ICElib.h> 33266e564dSmrg#include "ICElibint.h" 34266e564dSmrg#include <X11/Xtrans/Xtrans.h> 35266e564dSmrg#include "globals.h" 36266e564dSmrg 37266e564dSmrgstatic XtransConnInfo ConnectToPeer(char *networkIdsList, 38266e564dSmrg char **actualConnectionRet); 39266e564dSmrg 40266e564dSmrgIceConn 41c5629e66SmrgIceOpenConnection ( 42c5629e66Smrg char *networkIdsList, 43c5629e66Smrg IcePointer context, 44c5629e66Smrg Bool mustAuthenticate, 45c5629e66Smrg int majorOpcodeCheck, 46c5629e66Smrg int errorLength, 47c5629e66Smrg char *errorStringRet 48c5629e66Smrg) 49266e564dSmrg{ 50266e564dSmrg IceConn iceConn; 51266e564dSmrg int extra, i, j; 52266e564dSmrg int endian; 53266e564dSmrg Bool gotReply, ioErrorOccured; 54266e564dSmrg unsigned long setup_sequence; 55266e564dSmrg iceByteOrderMsg *pByteOrderMsg; 56266e564dSmrg iceConnectionSetupMsg *pSetupMsg; 57266e564dSmrg char *pData; 58266e564dSmrg IceReplyWaitInfo replyWait; 59266e564dSmrg _IceReply reply; 60266e564dSmrg int authUsableCount; 61266e564dSmrg int authUsableFlags[MAX_ICE_AUTH_NAMES]; 62266e564dSmrg int authIndices[MAX_ICE_AUTH_NAMES]; 63266e564dSmrg 64266e564dSmrg if (errorStringRet && errorLength > 0) 65266e564dSmrg *errorStringRet = '\0'; 66266e564dSmrg 67266e564dSmrg if (networkIdsList == NULL || *networkIdsList == '\0') 68266e564dSmrg { 69a3129944Smrg if (errorStringRet && errorLength > 0) { 70a3129944Smrg strncpy (errorStringRet, 71a3129944Smrg "networkIdsList argument is NULL", errorLength); 72a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 73a3129944Smrg } 74266e564dSmrg return (NULL); 75266e564dSmrg } 76266e564dSmrg 77266e564dSmrg /* 78266e564dSmrg * Check to see if we can use a previously created ICE connection. 79266e564dSmrg * 80266e564dSmrg * If iceConn->want_to_close is True, or iceConn->free_asap is True, 81266e564dSmrg * we can not use the iceConn. 82266e564dSmrg * 83266e564dSmrg * If 'context' is non-NULL, we will only use a previously opened ICE 84266e564dSmrg * connection if the specified 'context' is equal to the context 85266e564dSmrg * associated with the ICE connection, or if the context associated 86266e564dSmrg * with the ICE connection is NULL. 879ef0b394Smrg * 88266e564dSmrg * If 'majorOpcodeCheck' is non-zero, it will contain a protocol major 89266e564dSmrg * opcode that we should make sure is not already active on the ICE 901009a292Smrg * connection. Some clients will want two separate connections for the 91266e564dSmrg * same protocol to the same destination client. 92266e564dSmrg */ 93266e564dSmrg 94266e564dSmrg for (i = 0; i < _IceConnectionCount; i++) 95266e564dSmrg { 96266e564dSmrg char *strptr; 973bf3b463Smrg if ((strptr = strstr ( 98266e564dSmrg networkIdsList, _IceConnectionStrings[i])) != NULL) 99266e564dSmrg { 100266e564dSmrg char ch = *(strptr + strlen (_IceConnectionStrings[i])); 101266e564dSmrg if (ch == ',' || ch == '\0') 102266e564dSmrg { 103266e564dSmrg /* 104266e564dSmrg * OK, we found a connection. Make sure we can reuse it. 105266e564dSmrg */ 106266e564dSmrg 1071009a292Smrg IceConn iConn = _IceConnectionObjs[i]; 108266e564dSmrg 1091009a292Smrg if (iConn->want_to_close || iConn->free_asap || 1101009a292Smrg (context && iConn->context && 1111009a292Smrg iConn->context != context)) 112266e564dSmrg { 113266e564dSmrg /* force a new connection to be created */ 114266e564dSmrg break; 115266e564dSmrg } 116266e564dSmrg 117266e564dSmrg if (majorOpcodeCheck) 118266e564dSmrg { 1191009a292Smrg for (j = iConn->his_min_opcode; 1201009a292Smrg j <= iConn->his_max_opcode; j++) 121266e564dSmrg { 1221009a292Smrg if (iConn->process_msg_info[ 1231009a292Smrg j - iConn->his_min_opcode].in_use && 1241009a292Smrg iConn->process_msg_info[ 1251009a292Smrg j - iConn->his_min_opcode].my_opcode == 126266e564dSmrg majorOpcodeCheck) 127266e564dSmrg break; 128266e564dSmrg } 129266e564dSmrg 1301009a292Smrg if (j <= iConn->his_max_opcode || 1311009a292Smrg (iConn->protosetup_to_you && 1321009a292Smrg iConn->protosetup_to_you->my_opcode == 133266e564dSmrg majorOpcodeCheck)) 134266e564dSmrg { 135266e564dSmrg /* force a new connection to be created */ 136266e564dSmrg break; 137266e564dSmrg } 138266e564dSmrg } 139266e564dSmrg 1401009a292Smrg iConn->open_ref_count++; 1411009a292Smrg if (context && !iConn->context) 1421009a292Smrg iConn->context = context; 1431009a292Smrg return (iConn); 144266e564dSmrg } 145266e564dSmrg } 146266e564dSmrg } 147266e564dSmrg 148fb5e8d76Smrg if ((iceConn = malloc (sizeof (struct _IceConn))) == NULL) 149266e564dSmrg { 150a3129944Smrg if (errorStringRet && errorLength > 0) { 151a3129944Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 152a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 153a3129944Smrg } 154266e564dSmrg return (NULL); 155266e564dSmrg } 156266e564dSmrg 157266e564dSmrg 158266e564dSmrg /* 159266e564dSmrg * Open a network connection with the peer client. 160266e564dSmrg */ 161266e564dSmrg 162266e564dSmrg if ((iceConn->trans_conn = ConnectToPeer (networkIdsList, 163266e564dSmrg &iceConn->connection_string)) == NULL) 164266e564dSmrg { 165fb5e8d76Smrg free (iceConn); 166a3129944Smrg if (errorStringRet && errorLength > 0) { 167a3129944Smrg strncpy (errorStringRet, "Could not open network socket", errorLength); 168a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 169a3129944Smrg } 170266e564dSmrg return (NULL); 171266e564dSmrg } 172266e564dSmrg 173266e564dSmrg /* 174266e564dSmrg * Set close-on-exec so that programs that fork() don't get confused. 175266e564dSmrg */ 176266e564dSmrg 177266e564dSmrg _IceTransSetOption (iceConn->trans_conn, TRANS_CLOSEONEXEC, 1); 178266e564dSmrg 179266e564dSmrg iceConn->listen_obj = NULL; 180266e564dSmrg 181266e564dSmrg iceConn->connection_status = IceConnectPending; 182266e564dSmrg iceConn->io_ok = True; 183266e564dSmrg iceConn->dispatch_level = 0; 184266e564dSmrg iceConn->context = context; 185266e564dSmrg iceConn->my_ice_version_index = 0; 186266e564dSmrg iceConn->send_sequence = 0; 187266e564dSmrg iceConn->receive_sequence = 0; 188266e564dSmrg 189266e564dSmrg iceConn->vendor = NULL; 190266e564dSmrg iceConn->release = NULL; 191266e564dSmrg iceConn->outbuf = NULL; 192266e564dSmrg 193266e564dSmrg iceConn->scratch = NULL; 194266e564dSmrg iceConn->scratch_size = 0; 195266e564dSmrg 196266e564dSmrg iceConn->process_msg_info = NULL; 197266e564dSmrg 198266e564dSmrg iceConn->connect_to_you = NULL; 199266e564dSmrg iceConn->protosetup_to_you = NULL; 200266e564dSmrg 201266e564dSmrg iceConn->connect_to_me = NULL; 202266e564dSmrg iceConn->protosetup_to_me = NULL; 203266e564dSmrg 204fb5e8d76Smrg if ((iceConn->inbuf = iceConn->inbufptr = malloc (ICE_INBUFSIZE)) == NULL) 205266e564dSmrg { 206266e564dSmrg _IceFreeConnection (iceConn); 207a3129944Smrg if (errorStringRet && errorLength > 0) { 208a3129944Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 209a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 210a3129944Smrg } 211266e564dSmrg return (NULL); 212266e564dSmrg } 213266e564dSmrg 214266e564dSmrg iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE; 215266e564dSmrg 216fb5e8d76Smrg if ((iceConn->outbuf = iceConn->outbufptr = calloc (1, ICE_OUTBUFSIZE)) == NULL) 217266e564dSmrg { 218266e564dSmrg _IceFreeConnection (iceConn); 219a3129944Smrg if (errorStringRet && errorLength > 0) { 220a3129944Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 221a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 222a3129944Smrg } 223266e564dSmrg return (NULL); 224266e564dSmrg } 225266e564dSmrg 226266e564dSmrg iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE; 227266e564dSmrg 228266e564dSmrg iceConn->open_ref_count = 1; 229266e564dSmrg iceConn->proto_ref_count = 0; 230266e564dSmrg 231266e564dSmrg iceConn->skip_want_to_close = False; 232266e564dSmrg iceConn->want_to_close = False; 233266e564dSmrg iceConn->free_asap = False; 234266e564dSmrg 235266e564dSmrg iceConn->saved_reply_waits = NULL; 236266e564dSmrg iceConn->ping_waits = NULL; 237266e564dSmrg 238fb5e8d76Smrg iceConn->connect_to_you = malloc (sizeof (_IceConnectToYouInfo)); 239a3129944Smrg if (iceConn->connect_to_you == NULL) 240a3129944Smrg { 241a3129944Smrg _IceFreeConnection (iceConn); 242a3129944Smrg if (errorStringRet && errorLength > 0) { 243a3129944Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 244a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 245a3129944Smrg } 246a3129944Smrg return (NULL); 247a3129944Smrg } 248266e564dSmrg iceConn->connect_to_you->auth_active = 0; 249266e564dSmrg 250266e564dSmrg /* 251266e564dSmrg * Send our byte order. 252266e564dSmrg */ 253266e564dSmrg 254266e564dSmrg IceGetHeader (iceConn, 0, ICE_ByteOrder, 255266e564dSmrg SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pByteOrderMsg); 256266e564dSmrg 257266e564dSmrg endian = 1; 258266e564dSmrg if (*(char *) &endian) 259266e564dSmrg pByteOrderMsg->byteOrder = IceLSBfirst; 260266e564dSmrg else 261266e564dSmrg pByteOrderMsg->byteOrder = IceMSBfirst; 262266e564dSmrg 263266e564dSmrg IceFlush (iceConn); 264266e564dSmrg 265266e564dSmrg 266266e564dSmrg /* 267266e564dSmrg * Now read the ByteOrder message from the other client. 268266e564dSmrg * iceConn->swap should be set to the appropriate boolean 269266e564dSmrg * value after the call to IceProcessMessages. 270266e564dSmrg */ 271266e564dSmrg 272266e564dSmrg iceConn->waiting_for_byteorder = True; 273266e564dSmrg 274266e564dSmrg ioErrorOccured = False; 275266e564dSmrg while (iceConn->waiting_for_byteorder == True && !ioErrorOccured) 276266e564dSmrg { 277266e564dSmrg ioErrorOccured = (IceProcessMessages ( 278266e564dSmrg iceConn, NULL, NULL) == IceProcessMessagesIOError); 279266e564dSmrg } 280266e564dSmrg 281266e564dSmrg if (ioErrorOccured) 282266e564dSmrg { 283266e564dSmrg _IceFreeConnection (iceConn); 284a3129944Smrg if (errorStringRet && errorLength > 0) { 2851009a292Smrg strncpy (errorStringRet, "IO error occurred opening connection", 286a3129944Smrg errorLength); 287a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 288a3129944Smrg } 289266e564dSmrg return (NULL); 290266e564dSmrg } 291266e564dSmrg 292266e564dSmrg if (iceConn->connection_status == IceConnectRejected) 293266e564dSmrg { 294266e564dSmrg /* 295266e564dSmrg * We failed to get the required ByteOrder message. 296266e564dSmrg */ 297266e564dSmrg 298266e564dSmrg _IceFreeConnection (iceConn); 299a3129944Smrg if (errorStringRet && errorLength > 0) { 300a3129944Smrg strncpy (errorStringRet, 301a3129944Smrg "Internal error - did not receive the expected ByteOrder " 302a3129944Smrg "message", errorLength); 303a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 304a3129944Smrg } 305266e564dSmrg return (NULL); 306266e564dSmrg } 307266e564dSmrg 308266e564dSmrg 309266e564dSmrg /* 310266e564dSmrg * Determine which authentication methods are available for 311266e564dSmrg * the Connection Setup authentication. 312266e564dSmrg */ 313266e564dSmrg 314266e564dSmrg _IceGetPoValidAuthIndices ( 315266e564dSmrg "ICE", iceConn->connection_string, 316266e564dSmrg _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices); 317266e564dSmrg 318266e564dSmrg for (i = 0; i < _IceAuthCount; i++) 319266e564dSmrg { 320266e564dSmrg authUsableFlags[i] = 0; 321266e564dSmrg for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++) 322266e564dSmrg authUsableFlags[i] = (authIndices[j] == i); 323266e564dSmrg } 324266e564dSmrg 325266e564dSmrg 326266e564dSmrg /* 327266e564dSmrg * Now send a Connection Setup message. 328266e564dSmrg */ 329266e564dSmrg 330266e564dSmrg extra = STRING_BYTES (IceVendorString) + STRING_BYTES (IceReleaseString); 331266e564dSmrg 332266e564dSmrg for (i = 0; i < _IceAuthCount; i++) 333266e564dSmrg if (authUsableFlags[i]) 334266e564dSmrg { 335266e564dSmrg extra += STRING_BYTES (_IceAuthNames[i]); 336266e564dSmrg } 337266e564dSmrg 338266e564dSmrg extra += (_IceVersionCount * 4); 339266e564dSmrg 340266e564dSmrg IceGetHeaderExtra (iceConn, 0, ICE_ConnectionSetup, 341266e564dSmrg SIZEOF (iceConnectionSetupMsg), WORD64COUNT (extra), 342266e564dSmrg iceConnectionSetupMsg, pSetupMsg, pData); 343266e564dSmrg 344266e564dSmrg setup_sequence = iceConn->send_sequence; 345266e564dSmrg 346266e564dSmrg pSetupMsg->versionCount = _IceVersionCount; 347266e564dSmrg pSetupMsg->authCount = authUsableCount; 348266e564dSmrg pSetupMsg->mustAuthenticate = mustAuthenticate; 349266e564dSmrg 3501009a292Smrg if (_X_LIKELY(pData != NULL)) { 3511009a292Smrg STORE_STRING (pData, IceVendorString); 3521009a292Smrg STORE_STRING (pData, IceReleaseString); 353266e564dSmrg 3541009a292Smrg for (i = 0; i < _IceAuthCount; i++) 355266e564dSmrg { 3561009a292Smrg if (authUsableFlags[i]) 3571009a292Smrg { 3581009a292Smrg STORE_STRING (pData, _IceAuthNames[i]); 3591009a292Smrg } 360266e564dSmrg } 361266e564dSmrg 3621009a292Smrg for (i = 0; i < _IceVersionCount; i++) 3631009a292Smrg { 3641009a292Smrg STORE_CARD16 (pData, _IceVersions[i].major_version); 3651009a292Smrg STORE_CARD16 (pData, _IceVersions[i].minor_version); 3661009a292Smrg } 367266e564dSmrg } 3681009a292Smrg else { 3691009a292Smrg SEND_STRING (iceConn, IceVendorString); 3701009a292Smrg SEND_STRING (iceConn, IceReleaseString); 371266e564dSmrg 3721009a292Smrg for (i = 0; i < _IceAuthCount; i++) 3731009a292Smrg { 3741009a292Smrg if (authUsableFlags[i]) 3751009a292Smrg { 3761009a292Smrg SEND_STRING (iceConn, _IceAuthNames[i]); 3771009a292Smrg } 3781009a292Smrg } 379266e564dSmrg 3801009a292Smrg for (i = 0; i < _IceVersionCount; i++) 3811009a292Smrg { 3821009a292Smrg CARD16 v; 3831009a292Smrg v = _IceVersions[i].major_version; 3841009a292Smrg IceWriteData16 (iceConn, 2, &v); 3851009a292Smrg v = _IceVersions[i].minor_version; 3861009a292Smrg IceWriteData16 (iceConn, 2, &v); 3871009a292Smrg } 3881009a292Smrg } 3891009a292Smrg IceFlush (iceConn); 390266e564dSmrg 391266e564dSmrg /* 392266e564dSmrg * Process messages until we get a Connection Reply or an Error Message. 393266e564dSmrg * Authentication will take place behind the scenes. 394266e564dSmrg */ 395266e564dSmrg 396266e564dSmrg replyWait.sequence_of_request = setup_sequence; 397266e564dSmrg replyWait.major_opcode_of_request = 0; 398266e564dSmrg replyWait.minor_opcode_of_request = ICE_ConnectionSetup; 399266e564dSmrg replyWait.reply = (IcePointer) &reply; 400266e564dSmrg 401266e564dSmrg gotReply = False; 402266e564dSmrg ioErrorOccured = False; 403266e564dSmrg 4043bf3b463Smrg while (!gotReply && !ioErrorOccured && iceConn) 405266e564dSmrg { 406266e564dSmrg ioErrorOccured = (IceProcessMessages ( 407266e564dSmrg iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); 408266e564dSmrg 409266e564dSmrg if (ioErrorOccured) 410266e564dSmrg { 411a3129944Smrg if (errorStringRet && errorLength > 0) { 4121009a292Smrg strncpy (errorStringRet, "IO error occurred opening connection", 413a3129944Smrg errorLength); 414a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 415a3129944Smrg } 416266e564dSmrg _IceFreeConnection (iceConn); 417266e564dSmrg iceConn = NULL; 418266e564dSmrg } 419266e564dSmrg else if (gotReply) 420266e564dSmrg { 421266e564dSmrg if (reply.type == ICE_CONNECTION_REPLY) 422266e564dSmrg { 423266e564dSmrg if (reply.connection_reply.version_index >= _IceVersionCount) 424266e564dSmrg { 425a3129944Smrg if (errorStringRet && errorLength > 0) { 426a3129944Smrg strncpy (errorStringRet, 427a3129944Smrg "Got a bad version index in the Connection Reply", 428a3129944Smrg errorLength); 429a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 430a3129944Smrg } 431266e564dSmrg 432266e564dSmrg free (reply.connection_reply.vendor); 433266e564dSmrg free (reply.connection_reply.release); 434266e564dSmrg _IceFreeConnection (iceConn); 435266e564dSmrg iceConn = NULL; 436266e564dSmrg } 437266e564dSmrg else 438266e564dSmrg { 439266e564dSmrg iceConn->my_ice_version_index = 440266e564dSmrg reply.connection_reply.version_index; 441266e564dSmrg iceConn->vendor = reply.connection_reply.vendor; 442266e564dSmrg iceConn->release = reply.connection_reply.release; 443266e564dSmrg 444266e564dSmrg _IceConnectionObjs[_IceConnectionCount] = iceConn; 445266e564dSmrg _IceConnectionStrings[_IceConnectionCount] = 446266e564dSmrg iceConn->connection_string; 447266e564dSmrg _IceConnectionCount++; 448266e564dSmrg 449fb5e8d76Smrg free (iceConn->connect_to_you); 450266e564dSmrg iceConn->connect_to_you = NULL; 451266e564dSmrg 452266e564dSmrg iceConn->connection_status = IceConnectAccepted; 453266e564dSmrg } 454266e564dSmrg } 455266e564dSmrg else /* reply.type == ICE_CONNECTION_ERROR */ 456266e564dSmrg { 457266e564dSmrg /* Connection failed */ 458266e564dSmrg 459a3129944Smrg if (errorStringRet && errorLength > 0) { 460a3129944Smrg strncpy (errorStringRet, 461a3129944Smrg reply.connection_error.error_message, errorLength); 462a3129944Smrg errorStringRet[errorLength - 1] = '\0'; 463a3129944Smrg } 464266e564dSmrg 465266e564dSmrg free (reply.connection_error.error_message); 466266e564dSmrg 467266e564dSmrg _IceFreeConnection (iceConn); 468266e564dSmrg iceConn = NULL; 469266e564dSmrg } 470266e564dSmrg } 471266e564dSmrg } 472266e564dSmrg 473266e564dSmrg if (iceConn && _IceWatchProcs) 474266e564dSmrg { 475266e564dSmrg /* 476266e564dSmrg * Notify the watch procedures that an iceConn was opened. 477266e564dSmrg */ 478266e564dSmrg 479266e564dSmrg _IceConnectionOpened (iceConn); 480266e564dSmrg } 481266e564dSmrg 482266e564dSmrg return (iceConn); 483266e564dSmrg} 484266e564dSmrg 485266e564dSmrg 486a3129944Smrg 487266e564dSmrgIcePointer 488c5629e66SmrgIceGetConnectionContext ( 489c5629e66Smrg IceConn iceConn 490c5629e66Smrg) 491266e564dSmrg{ 492266e564dSmrg return (iceConn->context); 493266e564dSmrg} 494266e564dSmrg 495266e564dSmrg 496a3129944Smrg 497266e564dSmrg/* ------------------------------------------------------------------------- * 498266e564dSmrg * local routines * 499266e564dSmrg * ------------------------------------------------------------------------- */ 500266e564dSmrg 501266e564dSmrg#define ICE_CONNECTION_RETRIES 5 502266e564dSmrg 503266e564dSmrg 504266e564dSmrgstatic XtransConnInfo 505266e564dSmrgConnectToPeer (char *networkIdsList, char **actualConnectionRet) 506266e564dSmrg{ 507266e564dSmrg char addrbuf[256]; 508266e564dSmrg char* address; 509266e564dSmrg char *ptr, *endptr, *delim; 510266e564dSmrg int madeConnection = 0; 511fb5e8d76Smrg size_t len; 512fb5e8d76Smrg int retry, connect_stat; 513fb5e8d76Smrg size_t address_size; 514266e564dSmrg XtransConnInfo trans_conn = NULL; 515266e564dSmrg 516266e564dSmrg *actualConnectionRet = NULL; 517266e564dSmrg 518266e564dSmrg ptr = networkIdsList; 519266e564dSmrg len = strlen (networkIdsList); 520266e564dSmrg endptr = networkIdsList + len; 521266e564dSmrg 522266e564dSmrg if (len < sizeof addrbuf) 523266e564dSmrg { 524266e564dSmrg address = addrbuf; 525266e564dSmrg address_size = 256; 526266e564dSmrg } 527266e564dSmrg else 528266e564dSmrg { 529266e564dSmrg address = malloc (len + 1); 5303bf3b463Smrg if (address == NULL) 5313bf3b463Smrg return NULL; 532266e564dSmrg address_size = len; 5339ef0b394Smrg } 534266e564dSmrg 535266e564dSmrg while (ptr < endptr && !madeConnection) 536266e564dSmrg { 5373bf3b463Smrg if ((delim = strchr (ptr, ',')) == NULL) 538266e564dSmrg delim = endptr; 539266e564dSmrg 540266e564dSmrg len = delim - ptr; 541266e564dSmrg if (len > address_size - 1) 542266e564dSmrg len = address_size - 1; 543266e564dSmrg strncpy (address, ptr, len); 544266e564dSmrg address[len] = '\0'; 545266e564dSmrg 546266e564dSmrg ptr = delim + 1; 547266e564dSmrg 548266e564dSmrg for (retry = ICE_CONNECTION_RETRIES; retry >= 0; retry--) 549266e564dSmrg { 550266e564dSmrg if ((trans_conn = _IceTransOpenCOTSClient (address)) == NULL) 551266e564dSmrg { 552266e564dSmrg break; 553266e564dSmrg } 554266e564dSmrg 555266e564dSmrg if ((connect_stat = _IceTransConnect (trans_conn, address)) < 0) 556266e564dSmrg { 557266e564dSmrg _IceTransClose (trans_conn); 5581009a292Smrg trans_conn = NULL; 559266e564dSmrg 560266e564dSmrg if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 561266e564dSmrg { 562266e564dSmrg sleep(1); 563266e564dSmrg continue; 564266e564dSmrg } 565266e564dSmrg else 566266e564dSmrg break; 567266e564dSmrg } 568266e564dSmrg else 569266e564dSmrg { 570266e564dSmrg madeConnection = 1; 571266e564dSmrg break; 572266e564dSmrg } 573266e564dSmrg } 574266e564dSmrg } 575266e564dSmrg 5769ef0b394Smrg if (madeConnection) 577266e564dSmrg { 578266e564dSmrg /* 579266e564dSmrg * We need to return the actual network connection string 580266e564dSmrg */ 581266e564dSmrg 582266e564dSmrg *actualConnectionRet = strdup(address); 5839ef0b394Smrg 584266e564dSmrg /* 585266e564dSmrg * Return the file descriptor 586266e564dSmrg */ 5879ef0b394Smrg } 588266e564dSmrg else trans_conn = NULL; 589266e564dSmrg 590266e564dSmrg if (address != addrbuf) free (address); 591266e564dSmrg 592266e564dSmrg return trans_conn; 593266e564dSmrg} 594