/*----------------------------------------------------------------------------*/ static inline int ProcessRST(mtcp_manager_t mtcp, tcp_stream *cur_stream, uint32_t ack_seq) { /* TODO: we need reset validation logic */ /* the sequence number of a RST should be inside window */ /* (in SYN_SENT state, it should ack the previous SYN */ TRACE_DBG("Stream %d: TCP RESET (%s)\n", cur_stream->id, TCPStateToString(cur_stream)); #if DUMP_STREAM DumpStream(mtcp, cur_stream); #endif if (cur_stream->state <= TCP_ST_SYN_SENT) { /* not handled here */ return FALSE; } if (cur_stream->state == TCP_ST_SYN_RCVD) { if (ack_seq == cur_stream->rcv_nxt) { cur_stream->state = TCP_ST_CLOSED; cur_stream->close_reason = TCP_RESET; DestroyTCPStream(mtcp, cur_stream); } return TRUE; } /* if the application is already closed the connection, just destroy the it */ if (cur_stream->state == TCP_ST_FIN_WAIT_1 || cur_stream->state == TCP_ST_FIN_WAIT_2 || cur_stream->state == TCP_ST_LAST_ACK || cur_stream->state == TCP_ST_CLOSING || cur_stream->state == TCP_ST_TIME_WAIT) { cur_stream->state = TCP_ST_CLOSED; cur_stream->close_reason = TCP_ACTIVE_CLOSE; DestroyTCPStream(mtcp, cur_stream); return TRUE; } if (cur_stream->state >= TCP_ST_ESTABLISHED && cur_stream->state <= TCP_ST_CLOSE_WAIT) { /* ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, CLOSE_WAIT */ /* TODO: flush all the segment queues */ //NotifyConnectionReset(mtcp, cur_stream); } if (!(cur_stream->sndvar->on_closeq || cur_stream->sndvar->on_closeq_int || cur_stream->sndvar->on_resetq || cur_stream->sndvar->on_resetq_int)) { //cur_stream->state = TCP_ST_CLOSED; //DestroyTCPStream(mtcp, cur_stream); cur_stream->state = TCP_ST_CLOSE_WAIT; cur_stream->close_reason = TCP_RESET; RaiseCloseEvent(mtcp, cur_stream); } return TRUE; }
/*----------------------------------------------------------------------------*/ static inline int ProcessRST(mtcp_manager_t mtcp, tcp_stream *cur_stream, struct pkt_ctx *pctx) { /* TODO: we need reset validation logic */ /* the sequence number of a RST should be inside window */ /* (in SYN_SENT state, it should ack the previous SYN */ TRACE_DBG("Stream %d: TCP RESET (%s)\n", cur_stream->id, TCPStateToString(cur_stream)); #if DUMP_STREAM DumpStream(mtcp, cur_stream); #endif if (cur_stream->state <= TCP_ST_SYN_SENT) { /* not handled here */ return FALSE; } if (cur_stream->state == TCP_ST_SYN_RCVD) { /* ACK number of last sent ACK packet == rcv_nxt + 1*/ if (pctx->p.seq == 0 || #ifdef BE_RESILIENT_TO_PACKET_DROP pctx->p.seq == cur_stream->rcv_nxt + 1 || #endif pctx->p.ack_seq == cur_stream->rcv_nxt + 1) { cur_stream->state = TCP_ST_CLOSED_RSVD; cur_stream->cb_events |= MOS_ON_TCP_STATE_CHANGE; cur_stream->close_reason = TCP_RESET; cur_stream->actions |= MOS_ACT_DESTROY; } else { RAISE_DEBUG_EVENT(mtcp, cur_stream, "(SYN_RCVD): Ignore invalid RST. " "ack_seq expected: %u, ack_seq rcvd: %u\n", cur_stream->rcv_nxt + 1, pctx->p.ack_seq); } return TRUE; } /* if the application is already closed the connection, just destroy the it */ if (cur_stream->state == TCP_ST_FIN_WAIT_1 || cur_stream->state == TCP_ST_FIN_WAIT_2 || cur_stream->state == TCP_ST_LAST_ACK || cur_stream->state == TCP_ST_CLOSING || cur_stream->state == TCP_ST_TIME_WAIT) { cur_stream->state = TCP_ST_CLOSED_RSVD; cur_stream->close_reason = TCP_ACTIVE_CLOSE; cur_stream->cb_events |= MOS_ON_TCP_STATE_CHANGE; cur_stream->actions |= MOS_ACT_DESTROY; return TRUE; } if (cur_stream->state >= TCP_ST_ESTABLISHED && cur_stream->state <= TCP_ST_CLOSE_WAIT) { /* ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, CLOSE_WAIT */ /* TODO: flush all the segment queues */ //NotifyConnectionReset(mtcp, cur_stream); } if (!(cur_stream->sndvar->on_closeq || cur_stream->sndvar->on_closeq_int || cur_stream->sndvar->on_resetq || cur_stream->sndvar->on_resetq_int)) { //cur_stream->state = TCP_ST_CLOSED_RSVD; //cur_stream->actions |= MOS_ACT_DESTROY; cur_stream->state = TCP_ST_CLOSED_RSVD; cur_stream->cb_events |= MOS_ON_TCP_STATE_CHANGE; cur_stream->close_reason = TCP_RESET; if (HAS_STREAM_TYPE(cur_stream, MOS_SOCK_STREAM)) RaiseCloseEvent(mtcp, cur_stream); } return TRUE; }