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

📄 tcp_out.c

📁 最新的lwip 1.3.0版本在ucos平台上的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
  seg->p->len -= len;  seg->p->tot_len -= len;  seg->p->payload = seg->tcphdr;  seg->tcphdr->chksum = 0;#if CHECKSUM_GEN_TCP  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,             &(pcb->local_ip),             &(pcb->remote_ip),             IP_PROTO_TCP, seg->p->tot_len);#endif  TCP_STATS_INC(tcp.xmit);#if LWIP_NETIF_HWADDRHINT  {    struct netif *netif;    netif = ip_route(&pcb->remote_ip);    if(netif != NULL){      netif->addr_hint = &(pcb->addr_hint);      ip_output_if(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,                   pcb->tos, IP_PROTO_TCP, netif);      netif->addr_hint = NULL;    }  }#else /* LWIP_NETIF_HWADDRHINT*/  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,      IP_PROTO_TCP);#endif /* LWIP_NETIF_HWADDRHINT*/}/** * Send a TCP RESET packet (empty segment with RST flag set) either to * abort a connection or to show that there is no matching local connection * for a received segment. * * Called by tcp_abort() (to abort a local connection), tcp_input() (if no * matching local pcb was found), tcp_listen_input() (if incoming segment * has ACK flag set) and tcp_process() (received segment in the wrong state) * * Since a RST segment is in most cases not sent for an active connection, * tcp_rst() has a number of arguments that are taken from a tcp_pcb for * most other segment output functions. * * @param seqno the sequence number to use for the outgoing segment * @param ackno the acknowledge number to use for the outgoing segment * @param local_ip the local IP address to send the segment from * @param remote_ip the remote IP address to send the segment to * @param local_port the local TCP port to send the segment from * @param remote_port the remote TCP port to send the segment to */voidtcp_rst(u32_t seqno, u32_t ackno,  struct ip_addr *local_ip, struct ip_addr *remote_ip,  u16_t local_port, u16_t remote_port){  struct pbuf *p;  struct tcp_hdr *tcphdr;  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);  if (p == NULL) {      LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));      return;  }  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",              (p->len >= sizeof(struct tcp_hdr)));  tcphdr = p->payload;  tcphdr->src = htons(local_port);  tcphdr->dest = htons(remote_port);  tcphdr->seqno = htonl(seqno);  tcphdr->ackno = htonl(ackno);  TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);  tcphdr->wnd = htons(TCP_WND);  tcphdr->urgp = 0;  TCPH_HDRLEN_SET(tcphdr, 5);  tcphdr->chksum = 0;#if CHECKSUM_GEN_TCP  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,              IP_PROTO_TCP, p->tot_len);#endif  TCP_STATS_INC(tcp.xmit);  snmp_inc_tcpoutrsts();   /* Send output with hardcoded TTL since we have no access to the pcb */  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);  pbuf_free(p);  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));}/** * Requeue all unacked segments for retransmission * * Called by tcp_slowtmr() for slow retransmission. * * @param pcb the tcp_pcb for which to re-enqueue all unacked segments */voidtcp_rexmit_rto(struct tcp_pcb *pcb){  struct tcp_seg *seg;  if (pcb->unacked == NULL) {    return;  }  /* Move all unacked segments to the head of the unsent queue */  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);  /* concatenate unsent queue after unacked queue */  seg->next = pcb->unsent;  /* unsent queue is the concatenated queue (of unacked, unsent) */  pcb->unsent = pcb->unacked;  /* unacked queue is now empty */  pcb->unacked = NULL;  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);  /* increment number of retransmissions */  ++pcb->nrtx;  /* Don't take any RTT measurements after retransmitting. */  pcb->rttest = 0;  /* Do the actual retransmission */  tcp_output(pcb);}/** * Requeue the first unacked segment for retransmission * * Called by tcp_receive() for fast retramsmit. * * @param pcb the tcp_pcb for which to retransmit the first unacked segment */voidtcp_rexmit(struct tcp_pcb *pcb){  struct tcp_seg *seg;  if (pcb->unacked == NULL) {    return;  }  /* Move the first unacked segment to the unsent queue */  seg = pcb->unacked->next;  pcb->unacked->next = pcb->unsent;  pcb->unsent = pcb->unacked;  pcb->unacked = seg;  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);  ++pcb->nrtx;  /* Don't take any rtt measurements after retransmitting. */  pcb->rttest = 0;  /* Do the actual retransmission. */  snmp_inc_tcpretranssegs();  tcp_output(pcb);}/** * Send keepalive packets to keep a connection active although * no data is sent over it. * * Called by tcp_slowtmr() * * @param pcb the tcp_pcb for which to send a keepalive packet */voidtcp_keepalive(struct tcp_pcb *pcb){  struct pbuf *p;  struct tcp_hdr *tcphdr;  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",                          ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),                          ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",                           tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));     p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);     if(p == NULL) {    LWIP_DEBUGF(TCP_DEBUG,                 ("tcp_keepalive: could not allocate memory for pbuf\n"));    return;  }  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",              (p->len >= sizeof(struct tcp_hdr)));  tcphdr = p->payload;  tcphdr->src = htons(pcb->local_port);  tcphdr->dest = htons(pcb->remote_port);  tcphdr->seqno = htonl(pcb->snd_nxt - 1);  tcphdr->ackno = htonl(pcb->rcv_nxt);  TCPH_FLAGS_SET(tcphdr, 0);  tcphdr->wnd = htons(pcb->rcv_ann_wnd);  tcphdr->urgp = 0;  TCPH_HDRLEN_SET(tcphdr, 5);  tcphdr->chksum = 0;#if CHECKSUM_GEN_TCP  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,                                      IP_PROTO_TCP, p->tot_len);#endif  TCP_STATS_INC(tcp.xmit);  /* Send output to IP */#if LWIP_NETIF_HWADDRHINT  {    struct netif *netif;    netif = ip_route(&pcb->remote_ip);    if(netif != NULL){      netif->addr_hint = &(pcb->addr_hint);      ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,                   0, IP_PROTO_TCP, netif);      netif->addr_hint = NULL;    }  }#else /* LWIP_NETIF_HWADDRHINT*/  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);#endif /* LWIP_NETIF_HWADDRHINT*/  pbuf_free(p);  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",                          pcb->snd_nxt - 1, pcb->rcv_nxt));}/** * Send persist timer zero-window probes to keep a connection active * when a window update is lost. * * Called by tcp_slowtmr() * * @param pcb the tcp_pcb for which to send a zero-window probe packet */voidtcp_zero_window_probe(struct tcp_pcb *pcb){  struct pbuf *p;  struct tcp_hdr *tcphdr;  struct tcp_seg *seg;  LWIP_DEBUGF(TCP_DEBUG,               ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"               U16_F".%"U16_F".%"U16_F".%"U16_F"\n",               ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),               ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));  LWIP_DEBUGF(TCP_DEBUG,               ("tcp_zero_window_probe: tcp_ticks %"U32_F               "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",                tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));  seg = pcb->unacked;  if(seg == NULL)    seg = pcb->unsent;  if(seg == NULL)    return;  p = pbuf_alloc(PBUF_IP, TCP_HLEN + 1, PBUF_RAM);     if(p == NULL) {    LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));    return;  }  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",              (p->len >= sizeof(struct tcp_hdr)));  tcphdr = p->payload;  tcphdr->src = htons(pcb->local_port);  tcphdr->dest = htons(pcb->remote_port);  tcphdr->seqno = seg->tcphdr->seqno;  tcphdr->ackno = htonl(pcb->rcv_nxt);  TCPH_FLAGS_SET(tcphdr, 0);  tcphdr->wnd = htons(pcb->rcv_ann_wnd);  tcphdr->urgp = 0;  TCPH_HDRLEN_SET(tcphdr, 5);  /* Copy in one byte from the head of the unacked queue */  *((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;  tcphdr->chksum = 0;#if CHECKSUM_GEN_TCP  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,                                      IP_PROTO_TCP, p->tot_len);#endif  TCP_STATS_INC(tcp.xmit);  /* Send output to IP */#if LWIP_NETIF_HWADDRHINT  {    struct netif *netif;    netif = ip_route(&pcb->remote_ip);    if(netif != NULL){      netif->addr_hint = &(pcb->addr_hint);      ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,                   0, IP_PROTO_TCP, netif);      netif->addr_hint = NULL;    }  }#else /* LWIP_NETIF_HWADDRHINT*/  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);#endif /* LWIP_NETIF_HWADDRHINT*/  pbuf_free(p);  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F                          " ackno %"U32_F".\n",                          pcb->snd_nxt - 1, pcb->rcv_nxt));}#endif /* LWIP_TCP */

⌨️ 快捷键说明

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