⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_util.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  tcp_ip/tcp/tcp_util.c                                    *//*   Release: 2001.3                                                   *//*   Version: 2001.0                                                   *//*   Purpose: TCP Utility Routines                                     *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 2001, Blunk Microsystems                    *//*                      ALL RIGHTS RESERVED                            *//*                                                                     *//*   Licensees have the non-exclusive right to use, modify, or extract *//*   this computer program for software development at a single site.  *//*   This program may be resold or disseminated in executable format   *//*   only. The source code may not be redistributed or resold.         *//*                                                                     *//***********************************************************************/#include "../tcp_ipp.h"#include "tcp.h"#include "../ip/ip.h"/***********************************************************************//* Global Data Definitions                                             *//***********************************************************************/CircLink TcpLruList;/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*       state: Process expired state timer                            *//*                                                                     *//***********************************************************************/static void state(void *object){  SOCKET sock = object;  /*-------------------------------------------------------------------*/  /* If connection is established, this is a keep-alive timeout.       */  /*-------------------------------------------------------------------*/  if (sock->state == SS_ESTABLISHED)  {    --sock->snd_nxt;    TcpSendSeg(sock, 1);    NetTimerStart(&sock->out_tmr, sock->retrans_timeo);  }  /*-------------------------------------------------------------------*/  /* Otherwise, the connection has timed out and should be dropped.    */  /*-------------------------------------------------------------------*/  else  {    /*-----------------------------------------------------------------*/    /* Send RST, except for TIME_WAIT and SYN acknowledgment timeouts. */    /*-----------------------------------------------------------------*/    if ((sock->state != SS_TIMEWAIT) && ((sock->flags & TCPF_SYN) == 0))    {      sock->flags |= TCPF_RST;      TcpSendSeg(sock, 0);    }    /*-----------------------------------------------------------------*/    /* Drop the connection.                                            */    /*-----------------------------------------------------------------*/    TcpDrop(sock, ETIMEDOUT);  }}/***********************************************************************//*       delay: Send delayed acknowledgment                            *//*                                                                     *//***********************************************************************/static void delay(void *object){  SOCKET sock = object;  sock->flags |= SF_SENDFLG;  ++sock->reserve_cnt;  TcpOut(sock);}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//*   TcpRcvWin: Calculate receive window announcement                  *//*                                                                     *//*       Input: sock = pointer to socket control block                 *//*                                                                     *//***********************************************************************/ui16 TcpRcvWin(SOCKET sock){  int actual = sock->rb_size - sock->rb_count;  int limited = (actual > 0xFFFF) ? 0xFFFF : actual;  int rounded = limited - (limited % sock->rcv_mss);  /*-------------------------------------------------------------------*/  /* Check if buffer space allows announcement of a larger window that */  /* is an integer multiple of the maximum receive segment size.       */  /*-------------------------------------------------------------------*/  if (rounded > sock->rcv_win)    sock->rcv_win = rounded;  /*-------------------------------------------------------------------*/  /* Ensure non-zero announcement if space > half receive buffer size. */  /*-------------------------------------------------------------------*/  else if ((sock->rcv_win == 0) && (actual > (sock->rb_size >> 1)))    sock->rcv_win = limited;  /*-------------------------------------------------------------------*/  /* Return value is written to outbound TCP header, so convert order. */  /*-------------------------------------------------------------------*/  return htons((ui16)sock->rcv_win);}/***********************************************************************//*    TcpReset: Generate a reset in response to a bad packet           *//*                                                                     *//***********************************************************************/void TcpReset(void){  NetBuf *bufout;  Ip  *ip_out;  Tcp *tcp_out;  int seglen;  Route *route;  /*-------------------------------------------------------------------*/  /* Don't send a reset in response to a reset.                        */  /*-------------------------------------------------------------------*/  if (Net.Tcp->flags & TCPF_RST)    return;  /*-------------------------------------------------------------------*/  /* Find route for this destination.                                  */  /*-------------------------------------------------------------------*/  route = RtSearch(Net.Ip->src_ip);  if (route == NULL)  {    ++Stats.IpOutNoRoutes;    return;  }  /*-------------------------------------------------------------------*/  /* Get a buffer to use for the response.                             */  /*-------------------------------------------------------------------*/  bufout = tcpGetBuf(NIMHLEN + IPMHLEN + TCPMHLEN);  if (bufout == NULL) return;  /*-------------------------------------------------------------------*/  /* Calculate segment length (SYN and FIN each occupy a position).    */  /*-------------------------------------------------------------------*/  seglen = Net.Ip->length - (IP_HLEN(Net.Ip) + TCP_HLEN(Net.Tcp));  if (Net.Tcp->flags & TCPF_SYN)    ++seglen;  if (Net.Tcp->flags & TCPF_FIN)    ++seglen;  /*-------------------------------------------------------------------*/  /* Start TCP header fields.                                          */  /*-------------------------------------------------------------------*/  tcp_out = bufout->ip_data;  tcp_out->src_port = Net.Tcp->dst_port;  tcp_out->dst_port = Net.Tcp->src_port;  if (Net.Tcp->flags & TCPF_ACK)  {    tcp_out->seq_num = Net.Tcp->ack_num;    tcp_out->flags = TCPF_RST;  }  else  {    tcp_out->seq_num = 0;    tcp_out->flags = TCPF_RST | TCPF_ACK;  }  tcp_out->ack_num = Net.Tcp->seq_num + seglen;  tcp_out->offset = TCPHOFFSET;  tcp_out->window = tcp_out->urg_ptr = 0;  /*-------------------------------------------------------------------*/  /* Begin IP header initialization.                                   */  /*-------------------------------------------------------------------*/  ip_out = (Ip *)bufout->ip_pkt;  ip_out->protocol = IPT_TCP;  ip_out->dst_ip = Net.Ip->src_ip;  ip_out->src_ip = Net.Ip->dst_ip;  /*-------------------------------------------------------------------*/  /* Convert TCP header to network order.                              */  /*-------------------------------------------------------------------*/  tcp_out->seq_num  = htonl(tcp_out->seq_num);  tcp_out->ack_num  = htonl(tcp_out->ack_num);  tcp_out->window   = htons(tcp_out->window);  tcp_out->urg_ptr  = htons(tcp_out->urg_ptr);  /*-------------------------------------------------------------------*/  /* Calculate TCP checksum.                                           */  /*-------------------------------------------------------------------*/  bufout->length = TCPMHLEN;  tcp_out->cksum = 0;  tcp_out->cksum = TcpCheckSum(bufout);  /*-------------------------------------------------------------------*/  /* Pass to IP for delivery and track how many TCP segments are sent. */  /*-------------------------------------------------------------------*/  IpSend(route, bufout, TCPMHLEN, Net.Ip->ip_tos);  ++Stats.TcpOutSegs;}/***********************************************************************//*  TcpNewSock: Allocate TCP socket memory and kernel objects          *//*                                                                     *//*       Input: mode = WITH_BUFS or NO_BUFS                            *//*                                                                     *//*     Returns: pointer to new TCP socket control block                *//*                                                                     *//***********************************************************************/void *TcpNewSock(int mode){  SOCKET sock;  void *sbuf, *rbuf;  /*-------------------------------------------------------------------*/  /* Allocate socket control block if one is available.                */  /*-------------------------------------------------------------------*/  sock = SockAlloc(SOCK_STREAM);  if (sock == NULL)    return NULL;  /*-------------------------------------------------------------------*/  /* Get send and receive buffers, if requested.                       */  /*-------------------------------------------------------------------*/  sock->sb_size = (SOCK_SBUF_SIZE > 0xFFFF) ? 0xFFFF : SOCK_SBUF_SIZE;  sock->rb_size = SOCK_RBUF_SIZE;  if (mode == WITH_BUFS)  {    sbuf = tcpGetBuf(sock->sb_size);    if (sbuf == NULL)    {      SockRelease(sock);      return NULL;    }    rbuf = tcpGetBuf(sock->rb_size);    if (rbuf == NULL)    {      tcpRetBuf(&sbuf);      SockRelease(sock);      return NULL;    }  }  else    sbuf = rbuf = NULL;  sock->sbuf = sbuf;  sock->rbuf = rbuf;  /*-------------------------------------------------------------------*/  /* Initialize non-zero socket fields.                                */  /*-------------------------------------------------------------------*/  sock->out_state = TCPO_IDLE;  sock->ssthresh = sock->sb_size;  sock->retrans_timeo = INIT_RXT;  sock->state_tmr.action = state;  sock->state_tmr.object = sock;  INIT_TMR(sock->state_tmr);  sock->out_tmr.action = TcpOutTimeout;  sock->out_tmr.object = sock;  INIT_TMR(sock->out_tmr);  sock->ack_tmr.action = delay;  sock->ack_tmr.object = sock;  INIT_TMR(sock->ack_tmr);  /*-------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -