Print this page
12694 race between write() and shutdown() for unix sockets
@@ -23,11 +23,11 @@
* 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.
+ * Copyright 2020 Joyent, Inc.
*/
/*
* Multithreaded STREAMS Local Transport Provider.
*
@@ -374,12 +374,10 @@
*/
/*
* 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.
@@ -415,19 +413,10 @@
* 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 *);
@@ -821,10 +810,86 @@
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,12 +2018,13 @@
!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_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,11 +2446,11 @@
tli_err = TSYSERR;
unix_err = EINVAL;
goto error;
}
- tep->te_state = NEXTSTATE(TE_BIND_REQ, tep->te_state);
+ 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,11 +2486,11 @@
(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);
+ 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,31 +2501,31 @@
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);
+ 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);
+ 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);
+ tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state];
tli_err = TSYSERR;
unix_err = EINVAL;
goto error;
}
} else {
@@ -2467,20 +2533,20 @@
((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);
+ 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);
+ tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state];
tli_err = TBADADDR;
goto error;
}
#ifdef DEBUG
/*
@@ -2642,11 +2708,11 @@
tep->te_qlen = qlen;
if (qlen > 0)
tep->te_flag |= TL_LISTENER;
}
- tep->te_state = NEXTSTATE(TE_BIND_ACK, tep->te_state);
+ tep->te_state = nextstate[TE_BIND_ACK][tep->te_state];
/*
* send T_BIND_ACK message
*/
(void) qreply(wq, bamp);
return;
@@ -2659,11 +2725,11 @@
*/
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);
+ 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,11 +2771,11 @@
"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);
+ 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,11 +2791,11 @@
* We allow rebind with a new qlen value.
*/
tl_addr_unbind(tep);
}
- tep->te_state = NEXTSTATE(TE_OK_ACK1, tep->te_state);
+ tep->te_state = nextstate[TE_OK_ACK1][tep->te_state];
/*
* send T_OK_ACK
*/
tl_ok_ack(wq, ackmp, T_UNBIND_REQ);
}
@@ -2963,11 +3029,11 @@
tl_error_ack(wq, ackmp, TOUTSTATE, 0, T_CONN_REQ);
freemsg(mp);
return;
}
- tep->te_state = NEXTSTATE(TE_CONN_REQ, tep->te_state);
+ 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,11 +3067,11 @@
*/
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);
+ 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,11 +3288,11 @@
*/
/*
* ack validity of request and send the peer credential in the ACK.
*/
- tep->te_state = NEXTSTATE(TE_OK_ACK1, tep->te_state);
+ 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,11 +3362,11 @@
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);
+ 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,11 +3373,11 @@
/*
* 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);
+ 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,18 +3493,18 @@
tl_error_ack(wq, ackmp, TBADOPT, 0, prim);
freemsg(mp);
return;
}
- tep->te_state = NEXTSTATE(TE_CONN_RES, tep->te_state);
+ 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);
+ tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state];
tl_error_ack(wq, ackmp, TBADSEQ, 0, prim);
freemsg(mp);
return;
}
@@ -3448,11 +3514,11 @@
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);
+ tep->te_state = nextstate[TE_ERROR_ACK][tep->te_state];
tl_error_ack(wq, ackmp, TBADF, 0, prim);
freemsg(mp);
return;
}
@@ -3460,11 +3526,11 @@
* 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);
+ 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,11 +3544,11 @@
*/
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);
+ 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,11 +3560,11 @@
*/
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);
+ 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,11 +3578,11 @@
*/
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);
+ 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,15 +3696,15 @@
/*
* Now ack validity of request
*/
if (tep->te_nicon == 1) {
if (tep == acc_ep)
- tep->te_state = NEXTSTATE(TE_OK_ACK2, tep->te_state);
+ tep->te_state = nextstate[TE_OK_ACK2][tep->te_state];
else
- tep->te_state = NEXTSTATE(TE_OK_ACK3, tep->te_state);
+ tep->te_state = nextstate[TE_OK_ACK3][tep->te_state];
} else {
- tep->te_state = NEXTSTATE(TE_OK_ACK4, tep->te_state);
+ tep->te_state = nextstate[TE_OK_ACK4][tep->te_state];
}
/*
* send T_DISCON_IND now if client state validation failed earlier
*/
@@ -3687,11 +3753,11 @@
/*
* now start connecting the accepting endpoint
*/
if (tep != acc_ep)
- acc_ep->te_state = NEXTSTATE(TE_PASS_CONN, acc_ep->te_state);
+ 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,11 +3914,11 @@
freemsg(ccmp);
} else {
/*
* change client state on TE_CONN_CON event
*/
- cl_ep->te_state = NEXTSTATE(TE_CONN_CON, cl_ep->te_state);
+ 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,17 +4000,17 @@
}
/*
* 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);
+ 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);
+ tep->te_state = nextstate[TE_ERROR_ACK][new_state];
tl_error_ack(wq, ackmp, TSYSERR, EINVAL, T_DISCON_REQ);
freemsg(mp);
return;
}
@@ -3960,11 +4026,11 @@
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);
+ tep->te_state = nextstate[TE_ERROR_ACK][new_state];
tl_error_ack(wq, ackmp, TBADSEQ, 0, T_DISCON_REQ);
freemsg(mp);
return;
}
/*
@@ -3990,16 +4056,16 @@
/*
* prepare message to ack validity of request
*/
if (tep->te_nicon == 0) {
- new_state = NEXTSTATE(TE_OK_ACK1, new_state);
+ new_state = nextstate[TE_OK_ACK1][new_state];
} else {
if (tep->te_nicon == 1)
- new_state = NEXTSTATE(TE_OK_ACK2, new_state);
+ new_state = nextstate[TE_OK_ACK2][new_state];
else
- new_state = NEXTSTATE(TE_OK_ACK4, new_state);
+ new_state = nextstate[TE_OK_ACK4][new_state];
}
/*
* Flushing queues according to TPI. Using the old state.
*/
@@ -4095,16 +4161,16 @@
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);
+ nextstate[TE_DISCON_IND2]
+ [peer_tep->te_state];
else
peer_tep->te_state =
- NEXTSTATE(TE_DISCON_IND3,
- 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,11 +4629,11 @@
"tl_data:cots:out of state"));
tl_merror(wq, mp, EPROTO);
return;
}
/*
- * tep->te_state = NEXTSTATE(TE_DATA_REQ, tep->te_state);
+ * tep->te_state = nextstate[TE_DATA_REQ][tep->te_state];
* (State stays same on this event)
*/
/*
* get connected endpoint
@@ -4613,11 +4679,11 @@
prim->type = T_DATA_IND;
else
prim->type = T_OPTDATA_IND;
}
/*
- * peer_tep->te_state = NEXTSTATE(TE_DATA_IND, peer_tep->te_state);
+ * 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,11 +4796,11 @@
tep->te_state));
tl_merror(wq, mp, EPROTO);
return;
}
/*
- * tep->te_state = NEXTSTATE(TE_EXDATA_REQ, tep->te_state);
+ * tep->te_state = nextstate[TE_EXDATA_REQ][tep->te_state];
* (state stays same on this event)
*/
/*
* get connected endpoint
@@ -4772,11 +4838,11 @@
"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_tep->te_state = nextstate[TE_DATA_IND][peer_tep->te_state];
* (peer state stays same on this event)
*/
/*
* reuse message block
*/
@@ -4856,11 +4922,11 @@
} else {
freemsg(mp);
}
return;
}
- tep->te_state = NEXTSTATE(TE_ORDREL_REQ, tep->te_state);
+ 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,11 +4961,11 @@
(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);
+ peer_tep->te_state = nextstate[TE_ORDREL_IND][peer_tep->te_state];
/*
* reuse message block
*/
prim->type = T_ORDREL_IND;
@@ -4980,11 +5046,11 @@
freemsg(mp);
/*
* send indication message
*/
- tep->te_state = NEXTSTATE(TE_UDERROR_IND, tep->te_state);
+ tep->te_state = nextstate[TE_UDERROR_IND][tep->te_state];
qreply(wq, err_mp);
}
static void
@@ -5038,11 +5104,11 @@
"tl_wput:T_CONN_REQ:out of state"));
tl_merror(wq, mp, EPROTO);
return;
}
/*
- * tep->te_state = NEXTSTATE(TE_UNITDATA_REQ, tep->te_state);
+ * tep->te_state = nextstate[TE_UNITDATA_REQ][tep->te_state];
* (state does not change on this event)
*/
/*
* validate the message
@@ -5337,11 +5403,11 @@
mp = ui_mp;
}
/*
* send indication message
*/
- peer_tep->te_state = NEXTSTATE(TE_UNITDATA_IND, peer_tep->te_state);
+ peer_tep->te_state = nextstate[TE_UNITDATA_IND][peer_tep->te_state];
putnext(peer_tep->te_rq, mp);
}
@@ -5659,16 +5725,16 @@
/*
* Delete tip from the server list.
*/
if (srv_tep->te_nicon == 1) {
srv_tep->te_state =
- NEXTSTATE(TE_DISCON_IND2,
- 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);
+ 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,11 +5758,11 @@
* 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)));
+ 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,11 +5773,11 @@
*/
TL_QENABLE(peer_tep);
goto discon_peer;
}
peer_tep->te_state =
- NEXTSTATE(TE_ORDREL_IND, 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,12 +6017,12 @@
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);
+ 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);