int ret1, ret2;
/* Don't open new stream if the connection is closed */
- if (spop_conn->state >= SPOP_CS_ERROR || (spop_conn->flags & (SPOP_CF_ERR_PENDING|SPOP_CF_ERROR)))
+ if (spop_conn->state == SPOP_CS_CLOSED)
return 0;
/* May be negative if this setting has changed */
spop_strm_close(spop_strm);
}
-
- if (spop_conn->state >= SPOP_CS_ERROR || (spop_conn->flags & (SPOP_CF_ERR_PENDING|SPOP_CF_ERROR))) {
+ if (spop_conn->state == SPOP_CS_CLOSED || (spop_conn->flags & (SPOP_CF_ERR_PENDING|SPOP_CF_ERROR))) {
se_fl_set_error(spop_strm->sd);
spop_strm_propagate_term_flags(spop_conn, spop_strm);
if (!spop_strm->sd->abort_info.info) {
spop_set_frame_size(outbuf.area, outbuf.data - 4);
b_add(mbuf, outbuf.data);
spop_conn->flags |= SPOP_CF_DISCO_SENT;
- spop_conn->state = SPOP_CS_CLOSING;
ret = 1;
switch (spop_conn->errcode) {
TRACE_PROTO("SPOP AGENT HELLO frame rcvd", SPOP_EV_RX_FRAME|SPOP_EV_RX_HELLO, spop_conn->conn, 0, 0, (size_t[]){spop_conn->dfl});
b_del(&spop_conn->dbuf, spop_conn->dfl);
spop_conn->dfl = 0;
- spop_conn->state = SPOP_CS_FRAME_H;
spop_wake_unassigned_streams(spop_conn);
TRACE_LEAVE(SPOP_EV_RX_FRAME|SPOP_EV_RX_HELLO, spop_conn->conn);
return 1;
fail:
+ spop_conn->state = SPOP_CS_CLOSED;
+ TRACE_STATE("switching to CLOSED", SPOP_EV_RX_FRAME|SPOP_EV_RX_HELLO, spop_conn->conn);
TRACE_DEVEL("leaving on error", SPOP_EV_RX_FRAME|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
return 0;
}
sent = b_xfer(rxbuf, dbuf, flen);
BUG_ON(sent != flen);
+ /* b_del(&spop_conn->dbuf, sent); */
spop_conn->dfl -= sent;
end:
TRACE_ENTER(SPOP_EV_SPOP_CONN_WAKE, spop_conn->conn);
- if (spop_conn->state == SPOP_CS_CLOSED)
+ if (spop_conn->state >= SPOP_CS_ERROR)
goto out;
- if (unlikely(spop_conn->state < SPOP_CS_FRAME_H || spop_conn->state == SPOP_CS_CLOSING)) {
+ if (unlikely(spop_conn->state < SPOP_CS_FRAME_H)) {
if (spop_conn->state == SPOP_CS_HA_HELLO) {
TRACE_STATE("waiting AGENT HELLO frame to be sent", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO, spop_conn->conn);
goto out;
}
- else { /* AGENT_HELLO OR CLOSING */
- /* ensure that what is pending is a valid AGENT HELLO/DISCONNECT frame. */
- TRACE_STATE("receiving AGENT HELLO/DISCONNECT frame header", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR, spop_conn->conn);
+ if (spop_conn->state == SPOP_CS_AGENT_HELLO) {
+ /* ensure that what is pending is a valid AGENT HELLO frame. */
+ TRACE_STATE("receiving AGENT HELLO frame header", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR, spop_conn->conn);
if (!spop_get_frame_hdr(&spop_conn->dbuf, &hdr)) {
spop_conn->flags |= SPOP_CF_DEM_SHORT_READ;
TRACE_ERROR("header frame not available yet", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR, spop_conn->conn);
goto done;
}
- if (spop_conn->state == SPOP_CS_AGENT_HELLO && hdr.type != SPOP_FRM_T_AGENT_HELLO) {
+ if (hdr.sid || hdr.fid || hdr.type != SPOP_FRM_T_AGENT_HELLO || !(hdr.flags & SPOP_FRM_FL_FIN)) {
spop_conn_error(spop_conn, SPOP_ERR_INVALID);
spop_conn->state = SPOP_CS_CLOSED;
- TRACE_ERROR("unexpected frame type (AGENT HELLO expected)", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
- TRACE_STATE("switching to CLOSED", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
- goto done;
- }
-
- if ((hdr.type == SPOP_FRM_T_AGENT_HELLO || hdr.type == SPOP_FRM_T_AGENT_DISCON) && (hdr.sid || hdr.fid || !(hdr.flags & SPOP_FRM_FL_FIN))) {
- spop_conn_error(spop_conn, SPOP_ERR_INVALID);
- spop_conn->state = SPOP_CS_CLOSED;
- TRACE_ERROR("unexpected frame meta-data", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
+ TRACE_ERROR("unexpected frame type or flags", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
TRACE_STATE("switching to CLOSED", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
goto done;
}
break;
}
- spop_conn->state = SPOP_CS_FRAME_P;
-
new_frame:
spop_conn->dsi = hdr.sid;
spop_conn->dfi = hdr.fid;
spop_conn->dft = hdr.type;
spop_conn->dfl = hdr.len;
spop_conn->dff = hdr.flags;
+ spop_conn->state = SPOP_CS_FRAME_P;
TRACE_STATE("SPOP frame header rcvd, switching to FRAME_P", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR, spop_conn->conn);
/* Perform sanity check on the frame header */
switch (spop_conn->dft) {
case SPOP_FRM_T_AGENT_HELLO:
- ret = spop_conn_handle_hello(spop_conn);
+ if (spop_conn->state == SPOP_CS_FRAME_P)
+ ret = spop_conn_handle_hello(spop_conn);
break;
case SPOP_FRM_T_AGENT_DISCON:
- ret = spop_conn_handle_disconnect(spop_conn);
+ if (spop_conn->state == SPOP_CS_FRAME_P)
+ ret = spop_conn_handle_disconnect(spop_conn);
break;
case SPOP_FRM_T_AGENT_ACK:
if (spop_conn->state == SPOP_CS_FRAME_P)
b_del(&spop_conn->dbuf, ret);
spop_conn->dfl -= ret;
}
- if (!spop_conn->dfl && spop_conn->state != SPOP_CS_FRAME_P) {
+ if (!spop_conn->dfl) {
TRACE_STATE("switching to FRAME_H", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR, spop_conn->conn);
spop_conn->state = SPOP_CS_FRAME_H;
}
(b_data(&spop_conn->dbuf) || (spop_conn->flags & SPOP_CF_RCVD_SHUT))) {
spop_process_demux(spop_conn);
- if (spop_conn->state == SPOP_CS_CLOSED || (spop_conn->flags & SPOP_CF_ERROR))
+ if (spop_conn->state >= SPOP_CS_ERROR || (spop_conn->flags & SPOP_CF_ERROR))
b_reset(&spop_conn->dbuf);
if (b_room(&spop_conn->dbuf))