|
|
1.1 ! root 1: /* ssapinitiate.c - SPM: initiator */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.1 89/11/27 10:30:40 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.1 89/11/27 10:30:40 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: ssapinitiate.c,v $ ! 12: * Revision 7.1 89/11/27 10:30:40 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.0 89/11/23 22:25:27 mrose ! 16: * Release 6.0 ! 17: * ! 18: */ ! 19: ! 20: /* ! 21: * NOTICE ! 22: * ! 23: * Acquisition, use, and distribution of this module and related ! 24: * materials are subject to the restrictions of a license agreement. ! 25: * Consult the Preface in the User's Manual for the full terms of ! 26: * this agreement. ! 27: * ! 28: */ ! 29: ! 30: ! 31: /* LINTLIBRARY */ ! 32: ! 33: #include <stdio.h> ! 34: #include <signal.h> ! 35: #include "spkt.h" ! 36: #include "tailor.h" ! 37: ! 38: /* S-(ASYN-)CONNECT.REQUEST */ ! 39: ! 40: #define dotoken(requires,shift,bit,type) \ ! 41: { \ ! 42: if (requirements & requires) \ ! 43: switch (settings & (ST_MASK << shift)) { \ ! 44: case ST_INIT_VALUE << shift: \ ! 45: case ST_RESP_VALUE << shift: \ ! 46: case ST_CALL_VALUE << shift: \ ! 47: break; \ ! 48: \ ! 49: default: \ ! 50: return ssaplose (si, SC_PARAMETER, NULLCP, \ ! 51: "improper choice of %s token setting", type); \ ! 52: } \ ! 53: } ! 54: ! 55: /* */ ! 56: ! 57: int SAsynConnRequest (ref, calling, called, requirements, settings, isn, ! 58: data, cc, qos, sc, si, async) ! 59: struct SSAPref *ref; ! 60: struct SSAPaddr *calling, ! 61: *called; ! 62: int requirements, ! 63: settings, ! 64: cc, ! 65: async; ! 66: long isn; ! 67: char *data; ! 68: struct QOStype *qos; ! 69: struct SSAPconnect *sc; ! 70: struct SSAPindication *si; ! 71: { ! 72: SBV smask; ! 73: int result; ! 74: ! 75: isodetailor (NULLCP, 0); ! 76: ! 77: missingP (ref); ! 78: refmuchP (ref); ! 79: if (ref -> sr_vlen) ! 80: return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference"); ! 81: #ifdef notdef ! 82: missingP (calling); ! 83: #endif ! 84: missingP (called); ! 85: ! 86: if (requirements & ~SR_MYREQUIRE) ! 87: return ssaplose (si, SC_PARAMETER, NULLCP, ! 88: "requirements settings not supported"); ! 89: if ((requirements & SR_EXCEPTIONS) ! 90: && !(requirements & SR_HALFDUPLEX)) ! 91: return ssaplose (si, SC_PARAMETER, NULLCP, ! 92: "exception service requires half-duplex service"); ! 93: ! 94: dotokens (); ! 95: ! 96: if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) { ! 97: if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE) ! 98: if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1) ! 99: return ssaplose (si, SC_PARAMETER, NULLCP, ! 100: "bad choice for initial serial number"); ! 101: } ! 102: else ! 103: if (isn != SERIAL_NONE) ! 104: return ssaplose (si, SC_PARAMETER, NULLCP, ! 105: "initial serial number invalid given requirements"); ! 106: ! 107: if (data == NULL) ! 108: cc = 0; ! 109: else ! 110: if (cc > CONNECT_MAX) ! 111: return ssaplose (si, SC_PARAMETER, NULLCP, ! 112: "too much initial user data, %d octets", cc); ! 113: ! 114: #ifdef notdef ! 115: missingP (qos); ! 116: #endif ! 117: missingP (sc); ! 118: missingP (si); ! 119: ! 120: smask = sigioblock (); ! 121: ! 122: result = SConnRequestAux (ref, calling, called, requirements, settings, ! 123: isn, data, cc, qos, sc, si, async); ! 124: ! 125: (void) sigiomask (smask); ! 126: ! 127: return result; ! 128: } ! 129: ! 130: #undef dotoken ! 131: ! 132: /* */ ! 133: ! 134: static int SConnRequestAux (ref, calling, called, requirements, settings, isn, ! 135: data, cc, qos, sc, si, async) ! 136: struct SSAPref *ref; ! 137: struct SSAPaddr *calling, ! 138: *called; ! 139: int requirements, ! 140: settings, ! 141: cc, ! 142: async; ! 143: long isn; ! 144: char *data; ! 145: struct QOStype *qos; ! 146: struct SSAPconnect *sc; ! 147: struct SSAPindication *si; ! 148: { ! 149: int result; ! 150: register struct ssapkt *s; ! 151: register struct ssapblk *sb; ! 152: struct TSAPconnect tcs; ! 153: register struct TSAPconnect *tc = &tcs; ! 154: struct TSAPdisconnect tds; ! 155: register struct TSAPdisconnect *td = &tds; ! 156: ! 157: if ((sb = newsblk ()) == NULL) ! 158: return ssaplose (si, SC_CONGEST, NULLCP, "out of memory"); ! 159: if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0) ! 160: sb -> sb_maxtime = NOTOK; ! 161: else ! 162: sb -> sb_maxtime = qos -> qos_maxtime; ! 163: ! 164: if ((s = newspkt (SPDU_CN)) == NULL) { ! 165: (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory"); ! 166: goto out1; ! 167: } ! 168: ! 169: if (called -> sa_selectlen > 0) { ! 170: if (calling == NULLSA) { ! 171: static struct SSAPaddr sas; ! 172: ! 173: calling = &sas; ! 174: bzero ((char *) calling, sizeof *calling); ! 175: } ! 176: ! 177: if (calling -> sa_selectlen == 0) { ! 178: calling -> sa_port = ! 179: htons ((u_short) (0x8000 | (getpid () & 0x7fff))); ! 180: calling -> sa_selectlen = sizeof calling -> sa_port; ! 181: } ! 182: } ! 183: ! 184: if (calling) { ! 185: if (calling -> sa_selectlen > 0) { ! 186: s -> s_mask |= SMASK_CN_CALLING; ! 187: bcopy (calling -> sa_selector, s -> s_calling, ! 188: s -> s_callinglen = calling -> sa_selectlen); ! 189: } ! 190: sb -> sb_initiating = *calling; /* struct copy */ ! 191: } ! 192: ! 193: if (called -> sa_selectlen > 0) { ! 194: s -> s_mask |= SMASK_CN_CALLED; ! 195: bcopy (called -> sa_selector, s -> s_called, ! 196: s -> s_calledlen = called -> sa_selectlen); ! 197: } ! 198: sb -> sb_responding = *called; /* struct copy */ ! 199: ! 200: sb -> sb_requirements = requirements; ! 201: sb -> sb_settings = settings; ! 202: ! 203: if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA, ! 204: &called -> sa_addr, ! 205: (qos ? qos -> qos_extended : 0) ! 206: || ((requirements & SR_EXPEDITED) ? 1 : 0), ! 207: NULLCP, 0, qos, tc, td, async)) == NOTOK) { ! 208: (void) ts2sslose (si, "TAsynConnRequest", td); ! 209: ! 210: bzero ((char *) sc, sizeof *sc); ! 211: sc -> sc_sd = NOTOK; ! 212: sc -> sc_result = si -> si_abort.sa_reason; ! 213: ! 214: result = DONE; ! 215: goto out2; ! 216: } ! 217: ! 218: sb -> sb_fd = tc -> tc_sd; ! 219: if (qos && qos -> qos_sversion < 0) { ! 220: sb -> sb_version = SB_VRSN1; ! 221: sb -> sb_vrsnmask = SB_ALLVRSNS; ! 222: } ! 223: else ! 224: sb -> sb_vrsnmask = 1 << (sb -> sb_version = ! 225: (cc > SS_SIZE ! 226: || (qos && qos -> qos_sversion > 1)) ! 227: ? SB_VRSN2 : SB_VRSN1); ! 228: ! 229: s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN; ! 230: s -> s_cn_reference = *ref; /* struct copy */ ! 231: s -> s_options = CR_OPT_NULL; ! 232: s -> s_cn_version = sb -> sb_vrsnmask; ! 233: ! 234: if (isn != SERIAL_NONE) { ! 235: s -> s_mask |= SMASK_CN_ISN; ! 236: s -> s_isn = isn; ! 237: } ! 238: ! 239: if (cc > 0) { /* XXX: user musn't touch! */ ! 240: s -> s_mask |= SMASK_UDATA_PGI; ! 241: s -> s_udata = data, s -> s_ulen = cc; ! 242: } ! 243: else ! 244: s -> s_udata = NULL, s -> s_ulen = 0; ! 245: ! 246: sb -> sb_retry = s; ! 247: if (async) { ! 248: switch (result) { ! 249: case CONNECTING_1: ! 250: case CONNECTING_2: ! 251: sc -> sc_sd = sb -> sb_fd; ! 252: return result; ! 253: } ! 254: } ! 255: if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async) ! 256: result = OK; ! 257: return result; ! 258: ! 259: out2: ; ! 260: freespkt (s); ! 261: out1: ; ! 262: freesblk (sb); ! 263: ! 264: return result; ! 265: } ! 266: ! 267: /* S-ASYN-RETRY.REQUEST (pseudo) */ ! 268: ! 269: int SAsynRetryRequest (sd, sc, si) ! 270: int sd; ! 271: struct SSAPconnect *sc; ! 272: struct SSAPindication *si; ! 273: { ! 274: SBV smask; ! 275: int result; ! 276: register struct ssapblk *sb; ! 277: struct TSAPconnect tcs; ! 278: register struct TSAPconnect *tc = &tcs; ! 279: struct TSAPdisconnect tds; ! 280: register struct TSAPdisconnect *td = &tds; ! 281: ! 282: missingP (sc); ! 283: missingP (si); ! 284: ! 285: smask = sigioblock (); ! 286: ! 287: if ((sb = findsblk (sd)) == NULL) { ! 288: (void) sigiomask (smask); ! 289: return ssaplose (si, SC_PARAMETER, NULLCP, ! 290: "invalid session descriptor"); ! 291: } ! 292: if (sb -> sb_flags & SB_CONN) { ! 293: (void) sigiomask (smask); ! 294: return ssaplose (si, SC_OPERATION, NULLCP, ! 295: "session descriptor connected"); ! 296: } ! 297: ! 298: switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) { ! 299: case NOTOK: ! 300: (void) ts2sslose (si, "TAsynRetryRequest", td); ! 301: sb -> sb_fd = NOTOK; ! 302: ! 303: bzero ((char *) sc, sizeof *sc); ! 304: sc -> sc_sd = NOTOK; ! 305: sc -> sc_result = si -> si_abort.sa_reason; ! 306: ! 307: result = DONE; ! 308: freesblk (sb); ! 309: break; ! 310: ! 311: case CONNECTING_1: ! 312: case CONNECTING_2: ! 313: break; ! 314: ! 315: case DONE: ! 316: result = SAsynRetryAux (sb, tc, sc, si); ! 317: break; ! 318: } ! 319: ! 320: (void) sigiomask (smask); ! 321: ! 322: return result; ! 323: } ! 324: ! 325: /* S-ASYN-NEXT.REQUEST (pseudo) */ ! 326: ! 327: int SAsynNextRequest (sd, sc, si) ! 328: int sd; ! 329: struct SSAPconnect *sc; ! 330: struct SSAPindication *si; ! 331: { ! 332: SBV smask; ! 333: int result; ! 334: register struct ssapblk *sb; ! 335: struct TSAPconnect tcs; ! 336: register struct TSAPconnect *tc = &tcs; ! 337: struct TSAPdisconnect tds; ! 338: register struct TSAPdisconnect *td = &tds; ! 339: ! 340: missingP (sc); ! 341: missingP (si); ! 342: ! 343: smask = sigioblock (); ! 344: ! 345: if ((sb = findsblk (sd)) == NULL) { ! 346: (void) sigiomask (smask); ! 347: return ssaplose (si, SC_PARAMETER, NULLCP, ! 348: "invalid session descriptor"); ! 349: } ! 350: if (sb -> sb_flags & SB_CONN) { ! 351: (void) sigiomask (smask); ! 352: return ssaplose (si, SC_OPERATION, NULLCP, ! 353: "session descriptor connected"); ! 354: } ! 355: ! 356: switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) { ! 357: case NOTOK: ! 358: (void) ts2sslose (si, "TAsynRetryRequest", td); ! 359: sb -> sb_fd = NOTOK; ! 360: ! 361: bzero ((char *) sc, sizeof *sc); ! 362: sc -> sc_sd = NOTOK; ! 363: sc -> sc_result = si -> si_abort.sa_reason; ! 364: ! 365: result = DONE; ! 366: freesblk (sb); ! 367: break; ! 368: ! 369: case CONNECTING_1: ! 370: case CONNECTING_2: ! 371: break; ! 372: ! 373: case DONE: ! 374: result = SAsynRetryAux (sb, tc, sc, si); ! 375: break; ! 376: } ! 377: ! 378: (void) sigiomask (smask); ! 379: ! 380: return result; ! 381: } ! 382: ! 383: /* */ ! 384: ! 385: #define dotoken(requires,shift,bit,type) \ ! 386: { \ ! 387: if (sb -> sb_requirements & requires) { \ ! 388: switch (sb -> sb_settings & (ST_MASK << shift)) { \ ! 389: case ST_CALL_VALUE << shift: \ ! 390: if (!(s -> s_mask & SMASK_CN_SET)) \ ! 391: s -> s_settings = ST_INIT_VALUE << shift; \ ! 392: switch (s -> s_settings & (ST_MASK << shift)) { \ ! 393: case ST_INIT_VALUE << shift: \ ! 394: default: \ ! 395: sb -> sb_owned |= bit; \ ! 396: sc -> sc_settings |= ST_INIT_VALUE << shift; \ ! 397: break; \ ! 398: \ ! 399: case ST_RESP_VALUE << shift: \ ! 400: sc -> sc_settings |= ST_RESP_VALUE << shift; \ ! 401: break; \ ! 402: } \ ! 403: break; \ ! 404: \ ! 405: case ST_INIT_VALUE << shift: \ ! 406: sb -> sb_owned |= bit; \ ! 407: sc -> sc_settings |= ST_INIT_VALUE << shift; \ ! 408: break; \ ! 409: \ ! 410: case ST_RESP_VALUE << shift: \ ! 411: sc -> sc_settings |= ST_RESP_VALUE << shift; \ ! 412: break; \ ! 413: } \ ! 414: \ ! 415: if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \ ! 416: sc -> sc_please |= bit; \ ! 417: } \ ! 418: } ! 419: ! 420: /* */ ! 421: ! 422: static int SAsynRetryAux (sb, tc, sc, si) ! 423: register struct ssapblk *sb; ! 424: struct TSAPconnect *tc; ! 425: struct SSAPconnect *sc; ! 426: struct SSAPindication *si; ! 427: { ! 428: int len, ! 429: result; ! 430: register struct ssapkt *s; ! 431: ! 432: s = sb -> sb_retry; ! 433: sb -> sb_retry = NULL; ! 434: ! 435: sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */ ! 436: if (tc -> tc_expedited) ! 437: sb -> sb_flags |= SB_EXPD; ! 438: else ! 439: sb -> sb_requirements &= ~SR_EXPEDITED; ! 440: if (sb -> sb_version < SB_VRSN2) /* XXX */ ! 441: sb -> sb_tsdu_us = sb -> sb_tsdu_them = ! 442: GET_TSDU_SIZE (tc -> tc_tsdusize); ! 443: ! 444: if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) { ! 445: s -> s_mask |= SMASK_CN_TSDU; ! 446: s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us); ! 447: s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them); ! 448: } ! 449: ! 450: s -> s_mask |= SMASK_CN_REQ; ! 451: if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) { ! 452: s -> s_mask |= SMASK_CN_SET; ! 453: s -> s_settings = sb -> sb_settings; ! 454: } ! 455: ! 456: result = spkt2sd (s, sb -> sb_fd, 0, si); ! 457: s -> s_mask &= ~SMASK_UDATA_PGI; ! 458: s -> s_udata = NULL, s -> s_ulen = 0; ! 459: ! 460: freespkt (s); ! 461: if (result == NOTOK) ! 462: goto out1; ! 463: ! 464: if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) { ! 465: if (si -> si_abort.sa_reason == SC_TIMER) ! 466: (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out"); ! 467: result = NOTOK; ! 468: goto out2; ! 469: } ! 470: ! 471: bzero ((char *) sc, sizeof *sc); ! 472: switch (s -> s_code) { ! 473: case SPDU_AC: ! 474: sc -> sc_sd = sb -> sb_fd; ! 475: sc -> sc_result = SC_ACCEPT; ! 476: if (s -> s_mask & SMASK_CN_REF) ! 477: sc -> sc_connect = s -> s_cn_reference; /* struct copy */ ! 478: if (s -> s_mask & SMASK_CN_OPT) ! 479: sb -> sb_options = s -> s_options; ! 480: if (!(s -> s_mask & SMASK_CN_TSDU)) ! 481: s -> s_tsdu_init = s -> s_tsdu_resp = 0; ! 482: if (s -> s_tsdu_init < sb -> sb_tsdu_us) ! 483: sb -> sb_tsdu_us = s -> s_tsdu_init; ! 484: if (s -> s_tsdu_resp < sb -> sb_tsdu_them) ! 485: sb -> sb_tsdu_them = s -> s_tsdu_resp; ! 486: if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) { ! 487: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 488: "perposterous TSDU size (%d) for initiator", ! 489: sb -> sb_tsdu_us); ! 490: goto out2; ! 491: } ! 492: if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) { ! 493: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 494: "perposterous TSDU size (%d) for responder", ! 495: sb -> sb_tsdu_them); ! 496: goto out2; ! 497: } ! 498: if (s -> s_mask & SMASK_CN_VRSN) { ! 499: if (!(s -> s_cn_version & sb -> sb_vrsnmask)) { ! 500: /* not SC_VERSION */ ! 501: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 502: "version mismatch: expecting something in 0x%x, got 0x%x", ! 503: sb -> sb_vrsnmask, s -> s_cn_version); ! 504: goto out2; ! 505: } ! 506: sb -> sb_vrsnmask &= s -> s_cn_version; ! 507: } ! 508: sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2)) ! 509: ? SB_VRSN2 : SB_VRSN1; ! 510: if (s -> s_mask & SMASK_CN_ISN) ! 511: sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn; ! 512: else ! 513: sc -> sc_isn = SERIAL_NONE; ! 514: if (!(s -> s_mask & SMASK_CN_REQ)) { ! 515: s -> s_mask |= SMASK_CN_REQ; ! 516: s -> s_cn_require = SR_DEFAULT; ! 517: } ! 518: switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) { ! 519: case SR_HALFDUPLEX: ! 520: if (s -> s_cn_require & SR_HALFDUPLEX) ! 521: break; ! 522: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 523: "half-duplex negotiation failed"); ! 524: goto out2; ! 525: ! 526: case SR_DUPLEX: ! 527: if (s -> s_cn_require & SR_DUPLEX) ! 528: break; ! 529: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 530: "full-duplex negotiation failed"); ! 531: goto out2; ! 532: ! 533: default: ! 534: break; ! 535: } ! 536: #ifdef notdef /* screwy session protocol... */ ! 537: if (s -> s_cn_require & ~sb -> sb_requirements) { ! 538: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 539: "requirements negotiation failed"); ! 540: goto out2; ! 541: } ! 542: #endif ! 543: sb -> sb_requirements &= s -> s_cn_require; ! 544: switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) { ! 545: case SR_HALFDUPLEX: ! 546: case SR_DUPLEX: ! 547: break; ! 548: ! 549: default: ! 550: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 551: "half/full-duplex negotiation failed"); ! 552: goto out2; ! 553: } ! 554: if ((sb -> sb_requirements & SR_EXCEPTIONS) ! 555: && !(sb -> sb_requirements & SR_HALFDUPLEX)) { ! 556: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 557: "exception service requires half-duplex service"); ! 558: goto out2; ! 559: } ! 560: sc -> sc_requirements = sb -> sb_requirements; ! 561: sc -> sc_settings = sc -> sc_please = 0; ! 562: dotokens (); ! 563: if (s -> s_mask & SMASK_CN_CALLED) { ! 564: if ((len = s -> s_calledlen) ! 565: > sizeof sb -> sb_responding.sa_selector) ! 566: len = sizeof sb -> sb_responding.sa_selector; ! 567: bcopy (s -> s_called, sb -> sb_responding.sa_selector, ! 568: sb -> sb_responding.sa_selectlen = len); ! 569: } ! 570: sc -> sc_responding = sb -> sb_responding; /* struct copy */ ! 571: if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0) ! 572: sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC; ! 573: sc -> sc_qos = tc -> tc_qos; /* struct copy */ ! 574: sc -> sc_qos.qos_sversion = sb -> sb_version + 1; ! 575: sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0; ! 576: copySPKTdata (s, sc); ! 577: ! 578: freespkt (s); ! 579: sb -> sb_flags |= SB_CONN | SB_INIT; ! 580: ! 581: return DONE; ! 582: ! 583: case SPDU_RF: /* ignore s -> s_rf_disconnect */ ! 584: sc -> sc_sd = NOTOK; ! 585: sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata ! 586: : SC_NOTSPECIFIED; ! 587: if (s -> s_mask & SMASK_RF_REF) ! 588: sc -> sc_connect = s -> s_rf_reference; /* struct copy */ ! 589: if ((sc -> sc_result == SC_REJECTED) ! 590: && (s -> s_mask & SMASK_RF_REQ)) ! 591: sc -> sc_requirements = s -> s_rf_require; ! 592: if ((s -> s_mask & SMASK_CN_CALLED) ! 593: && (sc -> sc_result & SC_BASE)) { ! 594: if ((len = s -> s_calledlen) ! 595: > sizeof sb -> sb_responding.sa_selector) ! 596: len = sizeof sb -> sb_responding.sa_selector; ! 597: bcopy (s -> s_called, sb -> sb_responding.sa_selector, ! 598: sb -> sb_responding.sa_selectlen = len); ! 599: } ! 600: sc -> sc_responding = sb -> sb_responding; /* struct copy */ ! 601: sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1; ! 602: sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL; ! 603: si -> si_type = SI_ABORT; ! 604: { ! 605: register struct SSAPabort *sa = &si -> si_abort; ! 606: ! 607: sa -> sa_peer = 0; ! 608: sa -> sa_reason = sc -> sc_result; ! 609: sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc; ! 610: sa -> sa_realinfo = NULL; ! 611: } ! 612: result = DONE; ! 613: break; ! 614: ! 615: case SPDU_AB: ! 616: sc -> sc_sd = NOTOK; ! 617: sc -> sc_result = SC_ABORT; ! 618: si -> si_type = SI_ABORT; ! 619: { ! 620: register struct SSAPabort *sa = &si -> si_abort; ! 621: ! 622: if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER) ! 623: ? 1 : 0)) ! 624: sa -> sa_reason = sc -> sc_result; ! 625: sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen; ! 626: sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL; ! 627: } ! 628: result = DONE; ! 629: break; ! 630: ! 631: default: ! 632: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 633: "session protocol mangled: expecting 0x%x, got 0x%x", ! 634: SPDU_AC, s -> s_code); ! 635: break; ! 636: } ! 637: ! 638: out2: ; ! 639: freespkt (s); ! 640: out1: ; ! 641: freesblk (sb); ! 642: ! 643: return result; ! 644: } ! 645: ! 646: #undef dotoken
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.