📄 tcpstate.c
字号:
++Sock->reserve_cnt; Sock->lq_next = NULL; if (psock->lq_head == NULL) psock->lq_head = Sock; else psock->lq_tail->lq_next = Sock; psock->lq_tail = Sock; ++psock->q_count; /*-----------------------------------------------------------------*/ /* Release reservation on parent socket. */ /*-----------------------------------------------------------------*/ SockRelease(psock); Sock->psock = NULL; /*-----------------------------------------------------------------*/ /* Send "accepted" event to parent socket. */ /*-----------------------------------------------------------------*/ NetPostEvent(psock, SE_ACCEPTED); } /*-------------------------------------------------------------------*/ /* Socket is now established and connected. */ /*-------------------------------------------------------------------*/ ++Stats.TcpCurrEstab; Sock->state = SS_ESTABLISHED; Sock->flags |= SF_CONNECTED; /*-------------------------------------------------------------------*/ /* Stop SYN acknowledgment timer. */ /*-------------------------------------------------------------------*/ NetTimerStop(&Sock->state_tmr); /*-------------------------------------------------------------------*/ /* Process incoming data. */ /*-------------------------------------------------------------------*/ if (TcpData(Sock)) return; /*-------------------------------------------------------------------*/ /* If FIN received, move state to CLOSE_WAIT. */ /*-------------------------------------------------------------------*/ if (Sock->flags & SF_GOTFIN) Sock->state = SS_CLOSEWAIT;}/***********************************************************************//* established: Do ESTABLISHED state input processing *//* *//***********************************************************************/static void established(void){ /*-------------------------------------------------------------------*/ /* Abort connection for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { ++Stats.TcpEstabResets; if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments, window announcements, and data. */ /*-------------------------------------------------------------------*/ if (ack_and_win()) return; if (TcpData(Sock)) return; /*-------------------------------------------------------------------*/ /* If FIN received, move state to CLOSE_WAIT. */ /*-------------------------------------------------------------------*/ if (Sock->flags & SF_GOTFIN) Sock->state = SS_CLOSEWAIT; /*-------------------------------------------------------------------*/ /* Else if requested, restart keep-alive timer. */ /*-------------------------------------------------------------------*/ else if (Sock->flags & SF_KEEPALIVE) NetTimerStart(&Sock->state_tmr, KEEPALIVE_TIMEO);}/***********************************************************************//* closing: Do CLOSING state input processing *//* *//***********************************************************************/static void closing(void){ /*-------------------------------------------------------------------*/ /* Delete socket for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments and window announcements. */ /*-------------------------------------------------------------------*/ ack_and_win(); /*-------------------------------------------------------------------*/ /* Change state to TIME_WAIT if our FIN has been acknowledged. */ /*-------------------------------------------------------------------*/ if ((Sock->flags & SF_SNDFIN) == FALSE) set_time_wait();}/***********************************************************************//* fin_wait1: Do FIN_WAIT_1 state input processing *//* *//***********************************************************************/static void fin_wait1(void){ /*-------------------------------------------------------------------*/ /* Abort connection for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments, window announcements, and data. */ /*-------------------------------------------------------------------*/ if (ack_and_win()) return; if (TcpData(Sock)) return; /*-------------------------------------------------------------------*/ /* Check if our FIN has been acked. */ /*-------------------------------------------------------------------*/ if ((Sock->flags & SF_SNDFIN) == FALSE) { /*-----------------------------------------------------------------*/ /* Free memory used for send buffer. */ /*-----------------------------------------------------------------*/ tcpRetBuf(&Sock->sbuf); /*-----------------------------------------------------------------*/ /* If FIN received, change to TIME_WAIT, else FIN_WAIT2. */ /*-----------------------------------------------------------------*/ if (Sock->flags & SF_GOTFIN) set_time_wait(); else Sock->state = SS_FINWAIT2; } /*-------------------------------------------------------------------*/ /* Else if FIN has been received, change to CLOSING. */ /*-------------------------------------------------------------------*/ else if (Sock->flags & SF_GOTFIN) Sock->state = SS_CLOSING;}/***********************************************************************//* fin_wait2: Do FIN_WAIT_2 state input processing *//* *//***********************************************************************/static void fin_wait2(void){ /*-------------------------------------------------------------------*/ /* Abort connection for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments, window announcements, and data. */ /*-------------------------------------------------------------------*/ if (ack_and_win()) return; if (TcpData(Sock)) return; /*-------------------------------------------------------------------*/ /* If FIN received, move state to TIME_WAIT. */ /*-------------------------------------------------------------------*/ if (Sock->flags & SF_GOTFIN) set_time_wait();}/***********************************************************************//* time_wait: Do TIME_WAIT state input processing *//* *//***********************************************************************/static void time_wait(void){ /*-------------------------------------------------------------------*/ /* Ignore resets in TIME_WAIT (RFC1337). */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & TCPF_RST) return; /*-------------------------------------------------------------------*/ /* Delete socket and send RST in response to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & TCPF_SYN) { TcpReset(); TcpDrop(Sock, ECONNABORTED); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments and window announcements. */ /*-------------------------------------------------------------------*/ ack_and_win(); /*-------------------------------------------------------------------*/ /* If first reference, reschedule socket deletion. */ /*-------------------------------------------------------------------*/ if ((Sock->flags & SF_TW_RESTART) == FALSE) { Sock->flags |= SF_TW_RESTART; NetTimerStart(&Sock->state_tmr, TWO_MSL); }}/***********************************************************************//* close_wait: Do CLOSE_WAIT state input processing *//* *//***********************************************************************/static void close_wait(void){ /*-------------------------------------------------------------------*/ /* Abort connection for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { ++Stats.TcpEstabResets; if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments and window announcements. */ /*-------------------------------------------------------------------*/ ack_and_win();}/***********************************************************************//* last_ack: Do LAST_ACK state input processing *//* *//***********************************************************************/static void last_ack(void){ /*-------------------------------------------------------------------*/ /* Abort connection for RST or SYN, respond with RST to SYN. */ /*-------------------------------------------------------------------*/ if (Net.Tcp->flags & (TCPF_RST | TCPF_SYN)) { if (Net.Tcp->flags & TCPF_SYN) TcpReset(); TcpDrop(Sock, ECONNRESET); return; } /*-------------------------------------------------------------------*/ /* Handle acknowledgments and window announcements. */ /*-------------------------------------------------------------------*/ if (ack_and_win()) return; /*-------------------------------------------------------------------*/ /* If FIN ACKed, wake closer, close socket and free reservation. */ /*-------------------------------------------------------------------*/ if ((Sock->flags & SF_SNDFIN) == FALSE) TcpDrop(Sock, 0);}/***********************************************************************//* Local Utility Functions Definitions *//***********************************************************************//***********************************************************************//* set_time_wait: Set TIME_WAIT and schedule deletion in 2MSL *//* *//***********************************************************************/static void set_time_wait(void){ /*-------------------------------------------------------------------*/ /* Wake thread pending on graceful close. */ /*-------------------------------------------------------------------*/ NetPostEvent(Sock, SE_CLOSED); /*-------------------------------------------------------------------*/ /* Stop output and ack timers and set TIME_WAIT state. */ /*-------------------------------------------------------------------*/ NetTimerStop(&Sock->out_tmr); NetTimerStop(&Sock->ack_tmr); Sock->state = SS_TIMEWAIT; /*-------------------------------------------------------------------*/ /* If application has closed socket, strip socket resources. */ /*-------------------------------------------------------------------*/ if (Sock->api_access == NULL) TcpStrip(Sock, FREE_RBUF | FREE_SBUF); /*-------------------------------------------------------------------*/ /* Start 2MSL timer. */ /*-------------------------------------------------------------------*/ NetTimerStart(&Sock->state_tmr, TWO_MSL);}/***********************************************************************//* ack_and_win: Process acknowledgements and window announcements *//* *//***********************************************************************/static int ack_and_win(void){ int acked, win_update = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -