Print this page
12694 race between write() and shutdown() for unix sockets

*** 23,33 **** * Use is subject to license terms. */ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. ! * Copyright (c) 2018, Joyent, Inc. */ /* * Multithreaded STREAMS Local Transport Provider. * --- 23,33 ---- * Use is subject to license terms. */ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. ! * Copyright 2020 Joyent, Inc. */ /* * Multithreaded STREAMS Local Transport Provider. *
*** 374,385 **** */ /* * Local declarations */ - #define NEXTSTATE(EV, ST) ti_statetbl[EV][ST] - #define BADSEQNUM (-1) /* initial seq number used by T_DISCON_IND */ #define TL_BUFWAIT (10000) /* usecs to wait for allocb buffer timeout */ #define TL_TIDUSZ (64*1024) /* tidu size when "strmsgz" is unlimited (0) */ /* * Hash tables size. --- 374,383 ----
*** 415,433 **** * LOCAL MACROS */ #define T_ALIGN(p) P2ROUNDUP((p), sizeof (t_scalar_t)) /* - * EXTERNAL VARIABLE DECLARATIONS - * ----------------------------- - */ - /* - * state table defined in the OS space.c - */ - extern char ti_statetbl[TE_NOEVENTS][TS_NOSTATES]; - - /* * STREAMS DRIVER ENTRY POINTS PROTOTYPES */ static int tl_open(queue_t *, dev_t *, int, int, cred_t *); static int tl_close(queue_t *, int, cred_t *); static int tl_wput(queue_t *, mblk_t *); --- 413,422 ----
*** 821,830 **** --- 810,895 ---- static int tl_disable_early_connect = 0; static int tl_client_closing_when_accepting; static int tl_serializer_noswitch; + #define nr 127 /* not reachable */ + + #define TE_NOEVENTS 28 + + static char nextstate[TE_NOEVENTS][TS_NOSTATES] = { + /* STATES */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ + + /* Initialization events */ + + #define TE_BIND_REQ 0 /* bind request */ + { 1, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_UNBIND_REQ 1 /* unbind request */ + {nr, nr, nr, 2, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_OPTMGMT_REQ 2 /* manage options req */ + {nr, nr, nr, 4, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_BIND_ACK 3 /* bind acknowledment */ + {nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_OPTMGMT_ACK 4 /* manage options ack */ + {nr, nr, nr, nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_ERROR_ACK 5 /* error acknowledgment */ + {nr, 0, 3, nr, 3, 3, nr, nr, 7, nr, nr, nr, 6, 7, 9, 10, 11}, + #define TE_OK_ACK1 6 /* ok ack seqcnt == 0 */ + {nr, nr, 0, nr, nr, 6, nr, nr, nr, nr, nr, nr, 3, nr, 3, 3, 3}, + #define TE_OK_ACK2 7 /* ok ack seqcnt == 1, q == resq */ + {nr, nr, nr, nr, nr, nr, nr, nr, 9, nr, nr, nr, nr, 3, nr, nr, nr}, + #define TE_OK_ACK3 8 /* ok ack seqcnt == 1, q != resq */ + {nr, nr, nr, nr, nr, nr, nr, nr, 3, nr, nr, nr, nr, 3, nr, nr, nr}, + #define TE_OK_ACK4 9 /* ok ack seqcnt > 1 */ + {nr, nr, nr, nr, nr, nr, nr, nr, 7, nr, nr, nr, nr, 7, nr, nr, nr}, + + /* Connection oriented events */ + #define TE_CONN_REQ 10 /* connection request */ + {nr, nr, nr, 5, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_CONN_RES 11 /* connection response */ + {nr, nr, nr, nr, nr, nr, nr, 8, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_DISCON_REQ 12 /* disconnect request */ + {nr, nr, nr, nr, nr, nr, 12, 13, nr, 14, 15, 16, nr, nr, nr, nr, nr}, + #define TE_DATA_REQ 13 /* data request */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 9, nr, 11, nr, nr, nr, nr, nr}, + #define TE_EXDATA_REQ 14 /* expedited data request */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 9, nr, 11, nr, nr, nr, nr, nr}, + #define TE_ORDREL_REQ 15 /* orderly release req */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 10, nr, 3, nr, nr, nr, nr, nr}, + #define TE_CONN_IND 16 /* connection indication */ + {nr, nr, nr, 7, nr, nr, nr, 7, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_CONN_CON 17 /* connection confirmation */ + {nr, nr, nr, nr, nr, nr, 9, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_DATA_IND 18 /* data indication */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 9, 10, nr, nr, nr, nr, nr, nr}, + #define TE_EXDATA_IND 19 /* expedited data indication */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 9, 10, nr, nr, nr, nr, nr, nr}, + #define TE_ORDREL_IND 20 /* orderly release ind */ + {nr, nr, nr, nr, nr, nr, nr, nr, nr, 11, 3, nr, nr, nr, nr, nr, nr}, + #define TE_DISCON_IND1 21 /* disconnect indication seq == 0 */ + {nr, nr, nr, nr, nr, nr, 3, nr, nr, 3, 3, 3, nr, nr, nr, nr, nr}, + #define TE_DISCON_IND2 22 /* disconnect indication seq == 1 */ + {nr, nr, nr, nr, nr, nr, nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_DISCON_IND3 23 /* disconnect indication seq > 1 */ + {nr, nr, nr, nr, nr, nr, nr, 7, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_PASS_CONN 24 /* pass connection */ + {nr, nr, nr, 9, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + + + /* Unit data events */ + + #define TE_UNITDATA_REQ 25 /* unitdata request */ + {nr, nr, nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_UNITDATA_IND 26 /* unitdata indication */ + {nr, nr, nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + #define TE_UDERROR_IND 27 /* unitdata error indication */ + {nr, nr, nr, 3, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr, nr}, + }; + + + /* * LOCAL FUNCTION PROTOTYPES * ------------------------- */ static boolean_t tl_eqaddr(tl_addr_t *, tl_addr_t *);
*** 1953,1964 **** !peer_tep->te_closing && ((tep->te_state == TS_DATA_XFER) || (tep->te_state == TS_WREQ_ORDREL)) && (tep->te_wq != NULL) && (tep->te_wq->q_first == NULL) && ! ((peer_tep->te_state == TS_DATA_XFER) || ! (peer_tep->te_state == TS_WREQ_ORDREL)) && ((peer_rq = peer_tep->te_rq) != NULL) && (canputnext(peer_rq) || tep->te_closing)) { putnext(peer_rq, mp); } else if (tep->te_closing) { /* --- 2018,2030 ---- !peer_tep->te_closing && ((tep->te_state == TS_DATA_XFER) || (tep->te_state == TS_WREQ_ORDREL)) && (tep->te_wq != NULL) && (tep->te_wq->q_first == NULL) && ! (peer_tep->te_state == TS_DATA_XFER || ! peer_tep->te_state == TS_WIND_ORDREL || ! peer_tep->te_state == TS_WREQ_ORDREL) && ((peer_rq = peer_tep->te_rq) != NULL) && (canputnext(peer_rq) || tep->te_closing)) { putnext(peer_rq, mp); } else if (tep->te_closing) { /*
*** 2380,2390 **** tli_err = TSYSERR; unix_err = EINVAL; goto error; } ! tep->te_state = NEXTSTATE(TE_BIND_REQ, tep->te_state); ASSERT((bind->PRIM_type == O_T_BIND_REQ) || (bind->PRIM_type == T_BIND_REQ)); alen = bind->ADDR_length; --- 2446,2456 ---- tli_err = TSYSERR; unix_err = EINVAL; goto error; } ! tep->te_state = nextstate[TE_BIND_REQ][tep->te_state]; ASSERT((bind->PRIM_type == O_T_BIND_REQ) || (bind->PRIM_type == T_BIND_REQ)); alen = bind->ADDR_length;
*** 2420,2430 **** (aoff < 0) || (aoff + alen > msz)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid socket addr")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TSYSERR; unix_err = EINVAL; goto error; } /* Copy address from message to local buffer. */ --- 2486,2496 ---- (aoff < 0) || (aoff + alen > msz)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid socket addr")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TSYSERR; unix_err = EINVAL; goto error; } /* Copy address from message to local buffer. */
*** 2435,2465 **** if ((ux_addr.soua_magic != SOU_MAGIC_EXPLICIT) && (ux_addr.soua_magic != SOU_MAGIC_IMPLICIT)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid socket magic")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((ux_addr.soua_magic == SOU_MAGIC_IMPLICIT) && (ux_addr.soua_vp != NULL)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: implicit addr non-empty")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((ux_addr.soua_magic == SOU_MAGIC_EXPLICIT) && (ux_addr.soua_vp == NULL)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: explicit addr empty")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TSYSERR; unix_err = EINVAL; goto error; } } else { --- 2501,2531 ---- if ((ux_addr.soua_magic != SOU_MAGIC_EXPLICIT) && (ux_addr.soua_magic != SOU_MAGIC_IMPLICIT)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid socket magic")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((ux_addr.soua_magic == SOU_MAGIC_IMPLICIT) && (ux_addr.soua_vp != NULL)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: implicit addr non-empty")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((ux_addr.soua_magic == SOU_MAGIC_EXPLICIT) && (ux_addr.soua_vp == NULL)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: explicit addr empty")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TSYSERR; unix_err = EINVAL; goto error; } } else {
*** 2467,2486 **** ((ssize_t)(aoff + alen) > msz) || ((aoff + alen) < 0))) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid message")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((alen < 0) || (alen > (msz - sizeof (struct T_bind_req)))) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: bad addr in message")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tli_err = TBADADDR; goto error; } #ifdef DEBUG /* --- 2533,2552 ---- ((ssize_t)(aoff + alen) > msz) || ((aoff + alen) < 0))) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: invalid message")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TSYSERR; unix_err = EINVAL; goto error; } if ((alen < 0) || (alen > (msz - sizeof (struct T_bind_req)))) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_bind: bad addr in message")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tli_err = TBADADDR; goto error; } #ifdef DEBUG /*
*** 2642,2652 **** tep->te_qlen = qlen; if (qlen > 0) tep->te_flag |= TL_LISTENER; } ! tep->te_state = NEXTSTATE(TE_BIND_ACK, tep->te_state); /* * send T_BIND_ACK message */ (void) qreply(wq, bamp); return; --- 2708,2718 ---- tep->te_qlen = qlen; if (qlen > 0) tep->te_flag |= TL_LISTENER; } ! tep->te_state = nextstate[TE_BIND_ACK][tep->te_state]; /* * send T_BIND_ACK message */ (void) qreply(wq, bamp); return;
*** 2659,2669 **** */ tep->te_state = save_state; tl_memrecover(wq, mp, sizeof (struct T_error_ack)); return; } ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, tli_err, unix_err, save_prim_type); } /* * Process T_UNBIND_REQ. --- 2725,2735 ---- */ tep->te_state = save_state; tl_memrecover(wq, mp, sizeof (struct T_error_ack)); return; } ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, tli_err, unix_err, save_prim_type); } /* * Process T_UNBIND_REQ.
*** 2705,2715 **** "tl_wput:T_UNBIND_REQ:out of state, state=%d", tep->te_state)); tl_error_ack(wq, ackmp, TOUTSTATE, 0, T_UNBIND_REQ); return; } ! tep->te_state = NEXTSTATE(TE_UNBIND_REQ, tep->te_state); /* * TPI says on T_UNBIND_REQ: * send up a M_FLUSH to flush both * read and write queues --- 2771,2781 ---- "tl_wput:T_UNBIND_REQ:out of state, state=%d", tep->te_state)); tl_error_ack(wq, ackmp, TOUTSTATE, 0, T_UNBIND_REQ); return; } ! tep->te_state = nextstate[TE_UNBIND_REQ][tep->te_state]; /* * TPI says on T_UNBIND_REQ: * send up a M_FLUSH to flush both * read and write queues
*** 2725,2735 **** * We allow rebind with a new qlen value. */ tl_addr_unbind(tep); } ! tep->te_state = NEXTSTATE(TE_OK_ACK1, tep->te_state); /* * send T_OK_ACK */ tl_ok_ack(wq, ackmp, T_UNBIND_REQ); } --- 2791,2801 ---- * We allow rebind with a new qlen value. */ tl_addr_unbind(tep); } ! tep->te_state = nextstate[TE_OK_ACK1][tep->te_state]; /* * send T_OK_ACK */ tl_ok_ack(wq, ackmp, T_UNBIND_REQ); }
*** 2963,2973 **** tl_error_ack(wq, ackmp, TOUTSTATE, 0, T_CONN_REQ); freemsg(mp); return; } ! tep->te_state = NEXTSTATE(TE_CONN_REQ, tep->te_state); /* * get endpoint to connect to * check that peer with DEST addr is bound to addr * and has CONIND_number > 0 */ --- 3029,3039 ---- tl_error_ack(wq, ackmp, TOUTSTATE, 0, T_CONN_REQ); freemsg(mp); return; } ! tep->te_state = nextstate[TE_CONN_REQ][tep->te_state]; /* * get endpoint to connect to * check that peer with DEST addr is bound to addr * and has CONIND_number > 0 */
*** 3001,3011 **** */ if (err != 0) { if (peer_tep != NULL) tl_refrele(peer_tep); /* We are still expected to send T_OK_ACK */ ! tep->te_state = NEXTSTATE(TE_OK_ACK1, tep->te_state); tl_ok_ack(tep->te_wq, ackmp, T_CONN_REQ); tl_closeok(tep); dimp = tpi_ack_alloc(mp, sizeof (struct T_discon_ind), M_PROTO, T_DISCON_IND); if (dimp == NULL) { --- 3067,3077 ---- */ if (err != 0) { if (peer_tep != NULL) tl_refrele(peer_tep); /* We are still expected to send T_OK_ACK */ ! tep->te_state = nextstate[TE_OK_ACK1][tep->te_state]; tl_ok_ack(tep->te_wq, ackmp, T_CONN_REQ); tl_closeok(tep); dimp = tpi_ack_alloc(mp, sizeof (struct T_discon_ind), M_PROTO, T_DISCON_IND); if (dimp == NULL) {
*** 3222,3232 **** */ /* * ack validity of request and send the peer credential in the ACK. */ ! tep->te_state = NEXTSTATE(TE_OK_ACK1, tep->te_state); if (peer_tep != NULL && peer_tep->te_credp != NULL && confmp != NULL) { mblk_setcred(confmp, peer_tep->te_credp, peer_tep->te_cpid); } --- 3288,3298 ---- */ /* * ack validity of request and send the peer credential in the ACK. */ ! tep->te_state = nextstate[TE_OK_ACK1][tep->te_state]; if (peer_tep != NULL && peer_tep->te_credp != NULL && confmp != NULL) { mblk_setcred(confmp, peer_tep->te_credp, peer_tep->te_cpid); }
*** 3296,3306 **** tip->ti_tep = tep; tip->ti_seqno = tep->te_seqno; list_insert_tail(&peer_tep->te_iconp, tip); peer_tep->te_nicon++; ! peer_tep->te_state = NEXTSTATE(TE_CONN_IND, peer_tep->te_state); /* * send the T_CONN_IND message */ putnext(peer_tep->te_rq, cimp); --- 3362,3372 ---- tip->ti_tep = tep; tip->ti_seqno = tep->te_seqno; list_insert_tail(&peer_tep->te_iconp, tip); peer_tep->te_nicon++; ! peer_tep->te_state = nextstate[TE_CONN_IND][peer_tep->te_state]; /* * send the T_CONN_IND message */ putnext(peer_tep->te_rq, cimp);
*** 3307,3317 **** /* * Send a T_CONN_CON message for sockets. * Disable the queues until we have reached the correct state! */ if (confmp != NULL) { ! tep->te_state = NEXTSTATE(TE_CONN_CON, tep->te_state); noenable(wq); putnext(tep->te_rq, confmp); } /* * Now we need to increment tep reference because tep is referenced by --- 3373,3383 ---- /* * Send a T_CONN_CON message for sockets. * Disable the queues until we have reached the correct state! */ if (confmp != NULL) { ! tep->te_state = nextstate[TE_CONN_CON][tep->te_state]; noenable(wq); putnext(tep->te_rq, confmp); } /* * Now we need to increment tep reference because tep is referenced by
*** 3427,3444 **** tl_error_ack(wq, ackmp, TBADOPT, 0, prim); freemsg(mp); return; } ! tep->te_state = NEXTSTATE(TE_CONN_RES, tep->te_state); ASSERT(tep->te_state == TS_WACK_CRES); if (cres->SEQ_number < TL_MINOR_START && cres->SEQ_number >= BADSEQNUM) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:remote endpoint sequence number bad")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TBADSEQ, 0, prim); freemsg(mp); return; } --- 3493,3510 ---- tl_error_ack(wq, ackmp, TBADOPT, 0, prim); freemsg(mp); return; } ! tep->te_state = nextstate[TE_CONN_RES][tep->te_state]; ASSERT(tep->te_state == TS_WACK_CRES); if (cres->SEQ_number < TL_MINOR_START && cres->SEQ_number >= BADSEQNUM) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:remote endpoint sequence number bad")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TBADSEQ, 0, prim); freemsg(mp); return; }
*** 3448,3458 **** if (mod_hash_find_cb(tep->te_transport->tr_ai_hash, (mod_hash_key_t)(uintptr_t)cres->ACCEPTOR_id, (mod_hash_val_t *)&acc_ep, tl_find_callback) != 0) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:bad accepting endpoint")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TBADF, 0, prim); freemsg(mp); return; } --- 3514,3524 ---- if (mod_hash_find_cb(tep->te_transport->tr_ai_hash, (mod_hash_key_t)(uintptr_t)cres->ACCEPTOR_id, (mod_hash_val_t *)&acc_ep, tl_find_callback) != 0) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:bad accepting endpoint")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TBADF, 0, prim); freemsg(mp); return; }
*** 3460,3470 **** * Prevent acceptor from closing. */ if (!tl_noclose(acc_ep)) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:bad accepting endpoint")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TBADF, 0, prim); tl_refrele(acc_ep); freemsg(mp); return; } --- 3526,3536 ---- * Prevent acceptor from closing. */ if (!tl_noclose(acc_ep)) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:bad accepting endpoint")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TBADF, 0, prim); tl_refrele(acc_ep); freemsg(mp); return; }
*** 3478,3488 **** */ if ((tep != acc_ep) && (acc_ep->te_state != TS_IDLE)) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:accepting endpoint has no address bound," "state=%d", acc_ep->te_state)); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TOUTSTATE, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return; --- 3544,3554 ---- */ if ((tep != acc_ep) && (acc_ep->te_state != TS_IDLE)) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:accepting endpoint has no address bound," "state=%d", acc_ep->te_state)); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TOUTSTATE, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return;
*** 3494,3504 **** */ if ((tep == acc_ep) && (tep->te_nicon > 1)) { (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE | SL_ERROR, "tl_conn_res: > 1 conn_ind on listener-acceptor")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TBADF, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return; --- 3560,3570 ---- */ if ((tep == acc_ep) && (tep->te_nicon > 1)) { (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE | SL_ERROR, "tl_conn_res: > 1 conn_ind on listener-acceptor")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TBADF, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return;
*** 3512,3522 **** */ tip = tl_icon_find(tep, cres->SEQ_number); if (tip == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:no client in listener list")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, tep->te_state); tl_error_ack(wq, ackmp, TBADSEQ, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return; --- 3578,3588 ---- */ tip = tl_icon_find(tep, cres->SEQ_number); if (tip == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_conn_res:no client in listener list")); ! tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state]; tl_error_ack(wq, ackmp, TBADSEQ, 0, prim); freemsg(mp); tl_closeok(acc_ep); tl_refrele(acc_ep); return;
*** 3630,3644 **** /* * Now ack validity of request */ if (tep->te_nicon == 1) { if (tep == acc_ep) ! tep->te_state = NEXTSTATE(TE_OK_ACK2, tep->te_state); else ! tep->te_state = NEXTSTATE(TE_OK_ACK3, tep->te_state); } else { ! tep->te_state = NEXTSTATE(TE_OK_ACK4, tep->te_state); } /* * send T_DISCON_IND now if client state validation failed earlier */ --- 3696,3710 ---- /* * Now ack validity of request */ if (tep->te_nicon == 1) { if (tep == acc_ep) ! tep->te_state = nextstate[TE_OK_ACK2][tep->te_state]; else ! tep->te_state = nextstate[TE_OK_ACK3][tep->te_state]; } else { ! tep->te_state = nextstate[TE_OK_ACK4][tep->te_state]; } /* * send T_DISCON_IND now if client state validation failed earlier */
*** 3687,3697 **** /* * now start connecting the accepting endpoint */ if (tep != acc_ep) ! acc_ep->te_state = NEXTSTATE(TE_PASS_CONN, acc_ep->te_state); if (cl_ep == NULL) { /* * The client has already closed. Send up any queued messages * and change the state accordingly. --- 3753,3763 ---- /* * now start connecting the accepting endpoint */ if (tep != acc_ep) ! acc_ep->te_state = nextstate[TE_PASS_CONN][acc_ep->te_state]; if (cl_ep == NULL) { /* * The client has already closed. Send up any queued messages * and change the state accordingly.
*** 3848,3858 **** freemsg(ccmp); } else { /* * change client state on TE_CONN_CON event */ ! cl_ep->te_state = NEXTSTATE(TE_CONN_CON, cl_ep->te_state); putnext(cl_ep->te_rq, ccmp); } /* Mark the both endpoints as accepted */ cl_ep->te_flag |= TL_ACCEPTED; --- 3914,3924 ---- freemsg(ccmp); } else { /* * change client state on TE_CONN_CON event */ ! cl_ep->te_state = nextstate[TE_CONN_CON][cl_ep->te_state]; putnext(cl_ep->te_rq, ccmp); } /* Mark the both endpoints as accepted */ cl_ep->te_flag |= TL_ACCEPTED;
*** 3934,3950 **** } /* * Defer committing the state change until it is determined if * the message will be queued with the tl_icon or not. */ ! new_state = NEXTSTATE(TE_DISCON_REQ, tep->te_state); /* validate the message */ if (msz < sizeof (struct T_discon_req)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_discon_req:invalid message")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, new_state); tl_error_ack(wq, ackmp, TSYSERR, EINVAL, T_DISCON_REQ); freemsg(mp); return; } --- 4000,4016 ---- } /* * Defer committing the state change until it is determined if * the message will be queued with the tl_icon or not. */ ! new_state = nextstate[TE_DISCON_REQ][tep->te_state]; /* validate the message */ if (msz < sizeof (struct T_discon_req)) { (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_discon_req:invalid message")); ! tep->te_state = nextstate[TE_ERROR_ACK][new_state]; tl_error_ack(wq, ackmp, TSYSERR, EINVAL, T_DISCON_REQ); freemsg(mp); return; }
*** 3960,3970 **** tip = tl_icon_find(tep, dr->SEQ_number); if (tip == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_discon_req:no disconnect endpoint")); ! tep->te_state = NEXTSTATE(TE_ERROR_ACK, new_state); tl_error_ack(wq, ackmp, TBADSEQ, 0, T_DISCON_REQ); freemsg(mp); return; } /* --- 4026,4036 ---- tip = tl_icon_find(tep, dr->SEQ_number); if (tip == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 2, SL_TRACE | SL_ERROR, "tl_discon_req:no disconnect endpoint")); ! tep->te_state = nextstate[TE_ERROR_ACK][new_state]; tl_error_ack(wq, ackmp, TBADSEQ, 0, T_DISCON_REQ); freemsg(mp); return; } /*
*** 3990,4005 **** /* * prepare message to ack validity of request */ if (tep->te_nicon == 0) { ! new_state = NEXTSTATE(TE_OK_ACK1, new_state); } else { if (tep->te_nicon == 1) ! new_state = NEXTSTATE(TE_OK_ACK2, new_state); else ! new_state = NEXTSTATE(TE_OK_ACK4, new_state); } /* * Flushing queues according to TPI. Using the old state. */ --- 4056,4071 ---- /* * prepare message to ack validity of request */ if (tep->te_nicon == 0) { ! new_state = nextstate[TE_OK_ACK1][new_state]; } else { if (tep->te_nicon == 1) ! new_state = nextstate[TE_OK_ACK2][new_state]; else ! new_state = nextstate[TE_OK_ACK4][new_state]; } /* * Flushing queues according to TPI. Using the old state. */
*** 4095,4110 **** if (tip != NULL) { ASSERT(tep == tip->ti_tep); save_state = peer_tep->te_state; if (peer_tep->te_nicon == 1) peer_tep->te_state = ! NEXTSTATE(TE_DISCON_IND2, ! peer_tep->te_state); else peer_tep->te_state = ! NEXTSTATE(TE_DISCON_IND3, ! peer_tep->te_state); tl_freetip(peer_tep, tip); } ASSERT(tep->te_oconp != NULL); TL_UNCONNECT(tep->te_oconp); } --- 4161,4176 ---- if (tip != NULL) { ASSERT(tep == tip->ti_tep); save_state = peer_tep->te_state; if (peer_tep->te_nicon == 1) peer_tep->te_state = ! nextstate[TE_DISCON_IND2] ! [peer_tep->te_state]; else peer_tep->te_state = ! nextstate[TE_DISCON_IND3] ! [peer_tep->te_state]; tl_freetip(peer_tep, tip); } ASSERT(tep->te_oconp != NULL); TL_UNCONNECT(tep->te_oconp); }
*** 4563,4573 **** "tl_data:cots:out of state")); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = NEXTSTATE(TE_DATA_REQ, tep->te_state); * (State stays same on this event) */ /* * get connected endpoint --- 4629,4639 ---- "tl_data:cots:out of state")); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = nextstate[TE_DATA_REQ][tep->te_state]; * (State stays same on this event) */ /* * get connected endpoint
*** 4613,4623 **** prim->type = T_DATA_IND; else prim->type = T_OPTDATA_IND; } /* ! * peer_tep->te_state = NEXTSTATE(TE_DATA_IND, peer_tep->te_state); * (peer state stays same on this event) */ /* * send data to connected peer */ --- 4679,4689 ---- prim->type = T_DATA_IND; else prim->type = T_OPTDATA_IND; } /* ! * peer_tep->te_state = nextstate[TE_DATA_IND][peer_tep->te_state]; * (peer state stays same on this event) */ /* * send data to connected peer */
*** 4730,4740 **** tep->te_state)); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = NEXTSTATE(TE_EXDATA_REQ, tep->te_state); * (state stays same on this event) */ /* * get connected endpoint --- 4796,4806 ---- tep->te_state)); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = nextstate[TE_EXDATA_REQ][tep->te_state]; * (state stays same on this event) */ /* * get connected endpoint
*** 4772,4782 **** "tl_exdata:rx side:invalid state")); tl_merror(peer_tep->te_wq, mp, EPROTO); return; } /* ! * peer_tep->te_state = NEXTSTATE(TE_DATA_IND, peer_tep->te_state); * (peer state stays same on this event) */ /* * reuse message block */ --- 4838,4848 ---- "tl_exdata:rx side:invalid state")); tl_merror(peer_tep->te_wq, mp, EPROTO); return; } /* ! * peer_tep->te_state = nextstate[TE_DATA_IND][peer_tep->te_state]; * (peer state stays same on this event) */ /* * reuse message block */
*** 4856,4866 **** } else { freemsg(mp); } return; } ! tep->te_state = NEXTSTATE(TE_ORDREL_REQ, tep->te_state); /* * get connected endpoint */ if (((peer_tep = tep->te_conp) == NULL) || peer_tep->te_closing) { --- 4922,4932 ---- } else { freemsg(mp); } return; } ! tep->te_state = nextstate[TE_ORDREL_REQ][tep->te_state]; /* * get connected endpoint */ if (((peer_tep = tep->te_conp) == NULL) || peer_tep->te_closing) {
*** 4895,4905 **** (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_ordrel:rx side:invalid state")); tl_merror(peer_tep->te_wq, mp, EPROTO); return; } ! peer_tep->te_state = NEXTSTATE(TE_ORDREL_IND, peer_tep->te_state); /* * reuse message block */ prim->type = T_ORDREL_IND; --- 4961,4971 ---- (void) (STRLOG(TL_ID, tep->te_minor, 1, SL_TRACE | SL_ERROR, "tl_ordrel:rx side:invalid state")); tl_merror(peer_tep->te_wq, mp, EPROTO); return; } ! peer_tep->te_state = nextstate[TE_ORDREL_IND][peer_tep->te_state]; /* * reuse message block */ prim->type = T_ORDREL_IND;
*** 4980,4990 **** freemsg(mp); /* * send indication message */ ! tep->te_state = NEXTSTATE(TE_UDERROR_IND, tep->te_state); qreply(wq, err_mp); } static void --- 5046,5056 ---- freemsg(mp); /* * send indication message */ ! tep->te_state = nextstate[TE_UDERROR_IND][tep->te_state]; qreply(wq, err_mp); } static void
*** 5038,5048 **** "tl_wput:T_CONN_REQ:out of state")); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = NEXTSTATE(TE_UNITDATA_REQ, tep->te_state); * (state does not change on this event) */ /* * validate the message --- 5104,5114 ---- "tl_wput:T_CONN_REQ:out of state")); tl_merror(wq, mp, EPROTO); return; } /* ! * tep->te_state = nextstate[TE_UNITDATA_REQ][tep->te_state]; * (state does not change on this event) */ /* * validate the message
*** 5337,5347 **** mp = ui_mp; } /* * send indication message */ ! peer_tep->te_state = NEXTSTATE(TE_UNITDATA_IND, peer_tep->te_state); putnext(peer_tep->te_rq, mp); } --- 5403,5413 ---- mp = ui_mp; } /* * send indication message */ ! peer_tep->te_state = nextstate[TE_UNITDATA_IND][peer_tep->te_state]; putnext(peer_tep->te_rq, mp); }
*** 5659,5674 **** /* * Delete tip from the server list. */ if (srv_tep->te_nicon == 1) { srv_tep->te_state = ! NEXTSTATE(TE_DISCON_IND2, ! srv_tep->te_state); } else { srv_tep->te_state = ! NEXTSTATE(TE_DISCON_IND3, ! srv_tep->te_state); } ASSERT(*(uint32_t *)(d_mp->b_rptr) == T_DISCON_IND); putnext(srv_tep->te_rq, d_mp); tl_freetip(srv_tep, tip); --- 5725,5740 ---- /* * Delete tip from the server list. */ if (srv_tep->te_nicon == 1) { srv_tep->te_state = ! nextstate[TE_DISCON_IND2] ! [srv_tep->te_state]; } else { srv_tep->te_state = ! nextstate[TE_DISCON_IND3] ! [srv_tep->te_state]; } ASSERT(*(uint32_t *)(d_mp->b_rptr) == T_DISCON_IND); putnext(srv_tep->te_rq, d_mp); tl_freetip(srv_tep, tip);
*** 5692,5702 **** * send ordrel ind */ (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE, "tl_co_unconnect:connected: ordrel_ind state %d->%d", peer_tep->te_state, ! NEXTSTATE(TE_ORDREL_IND, peer_tep->te_state))); d_mp = tl_ordrel_ind_alloc(); if (d_mp == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE | SL_ERROR, "tl_co_unconnect:connected:" --- 5758,5768 ---- * send ordrel ind */ (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE, "tl_co_unconnect:connected: ordrel_ind state %d->%d", peer_tep->te_state, ! nextstate[TE_ORDREL_IND][peer_tep->te_state])); d_mp = tl_ordrel_ind_alloc(); if (d_mp == NULL) { (void) (STRLOG(TL_ID, tep->te_minor, 3, SL_TRACE | SL_ERROR, "tl_co_unconnect:connected:"
*** 5707,5717 **** */ TL_QENABLE(peer_tep); goto discon_peer; } peer_tep->te_state = ! NEXTSTATE(TE_ORDREL_IND, peer_tep->te_state); putnext(peer_tep->te_rq, d_mp); /* * Handle flow control case. This will generate * a t_discon_ind message with reason 0 if there --- 5773,5783 ---- */ TL_QENABLE(peer_tep); goto discon_peer; } peer_tep->te_state = ! nextstate[TE_ORDREL_IND][peer_tep->te_state]; putnext(peer_tep->te_rq, d_mp); /* * Handle flow control case. This will generate * a t_discon_ind message with reason 0 if there
*** 5951,5962 **** case T_OPTDATA_IND: case T_EXDATA_IND: putnext(tep->te_rq, mp); break; case T_ORDREL_IND: ! tep->te_state = NEXTSTATE(TE_ORDREL_IND, ! tep->te_state); putnext(tep->te_rq, mp); break; case T_DISCON_IND: tep->te_state = TS_IDLE; putnext(tep->te_rq, mp); --- 6017,6028 ---- case T_OPTDATA_IND: case T_EXDATA_IND: putnext(tep->te_rq, mp); break; case T_ORDREL_IND: ! tep->te_state = nextstate[TE_ORDREL_IND] ! [tep->te_state]; putnext(tep->te_rq, mp); break; case T_DISCON_IND: tep->te_state = TS_IDLE; putnext(tep->te_rq, mp);