📄 tcp.c
字号:
prt->state = SCLOSED;
/* Cleanup after ourselves. */
TCP_Cleanup(prt);
/* Increment the number of connection failures. */
SNMP_tcpAttemptFails_Inc;
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
return (1);
} /* end if */
if(flags & TSYN) /* need to send ACK */
{
prt->out.tcp_flags = TACK;
prt->in.nxt = GET32(p, TCP_SEQ_OFFSET) + 1;
prt->out.ack = GET32(p, TCP_ACK_OFFSET);
prt->out.size = GET16(p, TCP_WINDOW_OFFSET); /* credit window */
prt->maxSendWin = prt->out.size;
TCP_ACK_It (prt, 1);
if (flags & TACK)
{
prt->state = SEST;
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_ADD, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
/* Mark the socket as connected. */
SCK_CONNECTED(prt->p_socketd);
/* Delete the timeout timer. */
UTL_Timerunset(TCPRETRANS, (UNSIGNED)prt->pindex, (INT32)prt->out.ack);
/* Remove it from the window. */
TLS_Rmqueue(&prt->out, (INT32)prt->out.ack);
TLS_Put_Event (CONOPEN, (UNSIGNED)prt->p_socketd);
TCP_Check_MSS (prt, p, hlen);
} /* end if */
else
{
prt->state=SSYNR; /* syn received */
}
} /* end if */
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
break;
case SCWAIT:
/* The SYN flag should no be set. */
if(flags & TSYN)
{
/* Send a FIN and a RESET. */
prt->out.tcp_flags = TFIN | TRESET;
TCP_ACK_It(prt, 1);
/* Return to the closed state */
prt->state = SCLOSED;
/* Clean up the port. */
TCP_Cleanup(prt);
/* Increment the number of resets from the established state. */
SNMP_tcpEstabResets_Inc;
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
return(1);
}
TCP_ACK_Check (prt, p);
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
break;
case SLAST: /* check ack of FIN, or reset to see if we are done */
/* The SYN flag should no be set. */
if(flags & TSYN)
{
/* Send a FIN and a RESET. */
prt->out.tcp_flags = TFIN | TRESET;
TCP_ACK_It(prt, 1);
/* Return to the closed state */
prt->state = SCLOSED;
/* Clean up the port. */
TCP_Cleanup(prt);
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
return(1);
}
if (TCP_ACK_Check (prt, p) == NU_SUCCESS)
{
/* Return to the closed state */
prt->state = SCLOSED;
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
TCP_Cleanup(prt);
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
break;
}
if ((flags & TRESET)
|| (GET32(p, TCP_ACK_OFFSET) == prt->out.nxt) )
{
/* Return to the closed state */
prt->state = SCLOSED;
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
TCP_Cleanup(prt);
}
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
break;
case SFW1: /* waiting for ACK of FIN */
/* The SYN flag should no be set. */
if(flags & TSYN)
{
/* Send a FIN and a RESET. */
prt->out.tcp_flags = TFIN | TRESET;
TCP_ACK_It(prt, 1);
/* Return to the closed state */
prt->state = SCLOSED;
/* Clean up the port. */
TCP_Cleanup(prt);
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
return(1);
}
/* throw away data */
TCP_ACK_Check (prt, p);
prt->in.nxt = GET32(p, TCP_SEQ_OFFSET) + tlen - hlen;
if (flags & TRESET)
{
/* Return to the closed state */
prt->state = SCLOSED;
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
TCP_Cleanup(prt);
}
else if (((flags & TACK) != TACK) ||
(GET32(p, TCP_ACK_OFFSET) != prt->out.nxt))
{
if (flags & TFIN) /* got FIN, no ACK for mine */
{
prt->in.nxt++; /* account for FIN byte */
prt->out.tcp_flags = TACK; /* final byte has no FIN flag */
TCP_ACK_It (prt, 1);
prt->state = SCLOSING;
} /* end if */
else
{
prt->out.tcp_flags = TACK | TFIN;
/* Since we are already in SFW1 a FIN has already been sent. So
don't call Send_SYN_FIN here. That would create another packet
containing a FIN that would have a retransmit event associated
with it. */
TCP_ACK_It (prt, 1);
} /* end else */
} /* end if */
else if (flags & TFIN) /* ACK and FIN */
{
prt->in.nxt++; /* account for his FIN flag */
prt->out.tcp_flags = TACK; /* final byte has no FIN flag */
TCP_ACK_It (prt, 1);
/* If the socket has not been deallocated, restart any tasks
pending on this port. */
if ( (prt->p_socketd >= 0) && (SCK_Sockets[prt->p_socketd] != NU_NULL) )
{
/* Restart any tasks pending on this connection. */
if (SCK_Sockets[prt->p_socketd]->s_RXTask != NU_NULL)
NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_RXTask);
if (SCK_Sockets[prt->p_socketd]->s_TXTask != NU_NULL)
NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_TXTask);
if (SCK_Sockets[prt->p_socketd]->s_CLSTask != NU_NULL)
NU_Resume_Task(SCK_Sockets[prt->p_socketd]->s_CLSTask);
}
UTL_Timerset(TCPTIMEWAIT, (UNSIGNED)prt->pindex, WAITTIME, (INT32)0);
prt->state = STWAIT; /* we are done */
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
} /* end if */
else
{ /* got ACK, no FIN */
prt->out.tcp_flags = TACK; /* final pkt has no FIN flag */
prt->state = SFW2;
/* Timeout this connection if a FIN is not received from the
foreign host. We will use a timeout of 5 times the current
retransmit timeout. */
UTL_Timerset(TCPCLOSETIMEOUTSFW2, (UNSIGNED)prt->pindex,
(UNSIGNED)(5 * prt->p_rto), (INT32)0);
} /* end else */
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
break;
case SFW2:
/* The SYN flag should no be set. */
if(flags & TSYN)
{
/* Send a FIN and a RESET. */
prt->out.tcp_flags = TFIN | TRESET;
TCP_ACK_It(prt, 1);
/* Return to the closed state */
prt->state = SCLOSED;
/* Clean up the port. */
TCP_Cleanup(prt);
/* Drop the packet by placing it back on the buffer_freelist. */
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
return(1);
}
/* want FIN */
TCP_ACK_Check (prt, p);
prt->in.nxt = GET32(p, TCP_SEQ_OFFSET) + tlen - hlen;
if(flags & TRESET)
{
UTL_Timerunset(TCPCLOSETIMEOUTSFW2, (UNSIGNED)prt->pindex, (INT32)1);
/* Return to the closed state */
prt->state = SCLOSED;
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(tcp_laddr, 0, prt->tcp_laddr);
PUT32(tcp_faddr, 0, prt->tcp_faddr);
SNMP_tcpConnTableUpdate(SNMP_DELETE, SEST, tcp_laddr, (UNSIGNED)(prt->in.port),
tcp_faddr, (UNSIGNED)(prt->out.port));
#endif
TCP_Cleanup(prt);
}
else if(flags & TFIN) /* we got FIN */
{
UTL_Timerunset(TCPCLOSETIMEOUTSFW2, (UNSIGNED)prt->pindex, (INT32)1);
prt->in.nxt++; /* count his FIN byte */
TCP_ACK_It (prt, 1);
/* If the socket has not been deallocated, restart any tasks
pending on this port. */
if ( (prt->p_socketd >= 0) && (SCK_Sockets[prt->p_socketd] != NU_NULL) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -