Beispiel #1
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
#if UIP_TCP
  u16_t tcplen, len1, len2;

  /* We only try to split maximum sized TCP segments. */
  if(BUF->proto == UIP_PROTO_TCP  && uip_len == UIP_BUFSIZE) {

    tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN + UIP_LLH_LEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = (uip_len - UIP_LLH_LEN) >> 8;
    BUF->len[1] = (uip_len - UIP_LLH_LEN) & 0xff;
#endif /* UIP_CONF_IPV6 */

    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the first packet. */
#if UIP_CONF_IPV6
    tcpip_ipv6_output();
#else
	RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
#endif /* UIP_CONF_IPV6 */

    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is determined by the length of the first
       packet (len1). */
    uip_len = len2 + UIP_TCPIP_HLEN + UIP_LLH_LEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = (uip_len  - UIP_LLH_LEN) >> 8;
    BUF->len[1] = (uip_len - UIP_LLH_LEN) & 0xff;
#endif /* UIP_CONF_IPV6 */

    memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];

    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the second packet. */
#if UIP_CONF_IPV6
    tcpip_ipv6_output();
#else
	RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
#endif /* UIP_CONF_IPV6 */
    return;
  }
Beispiel #2
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(chanend mac_tx)
{
  u16_t tcplen, len1, len2;

  /* We only try to split maximum sized TCP segments. */
  if(BUF->proto == UIP_PROTO_TCP &&
     uip_len + UIP_TCPIP_HLEN > UIP_BUFSIZE/2) {
//    printstr("split");
    tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */
    
    uip_len += UIP_LLH_LEN;
    /* Transmit the first packet. */
    /*    uip_fw_output();*/
    /*    tcpip_output(); */
    xcoredev_send(mac_tx);

    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is detemined by the length of the first
       packet (len1). */    
    uip_len = len2 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* UIP_CONF_IPV6 */
    
    /*    uip_appdata += len1;*/
    memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !UIP_CONF_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* UIP_CONF_IPV6 */

    /* Transmit the second packet. */
    /*    uip_fw_output();*/
    /*tcpip_output();*/
    uip_len += UIP_LLH_LEN;
    xcoredev_send(mac_tx);
  } else {
// The purpose of this function is to defeat Neagles Algorithm.  For packets
// over half of the size of the max frame size (which we assume to be part of
// a data stream and therefore need to be ACKed quickly) we break the packet
// in two, which means that the Neagles Algorithm effect of ACKing only every
// other packet will generate ACKs for us for each transmission.
//
// Without this, since we do not have a sliding window, and therefore do not
// transmit packet 2 until packet 1 has been acknowledged, we have to wait
// until the other end times out of the 300ms delay before sending us an ACK.
void
uip_split_output(chanend mac_tx)
{
	u16_t tcplen, len1, len2;

	if (BUF->proto == UIP_PROTO_TCP) {
          int data_len = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
          if (data_len > ACTUAL_UIP_PACKET_SPLIT_THRESHOLD) {
			tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
			/* Split the segment in two, making sure the first segment is an
			 * integer number of words */
			len1 = (tcplen / 2) & ~3;
			len2 = tcplen - len1;

			/* Create the first packet. This is done by altering the length
			 field of the IP header and updating the checksums. */
			uip_len = len1 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
			/* For IPv6, the IP length field does not include the IPv6 IP header length. */
			BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
			BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else
			BUF->len[0] = uip_len >> 8;
			BUF->len[1] = uip_len & 0xff;
#endif

			uip_split_output_send(mac_tx);

			/* Now, create the second packet. To do this, it is not enough to
			 just alter the length field, but we must also update the TCP
			 sequence number and point the uip_appdata to a new place in
			 memory. This place is determined by the length of the first
			 packet (len1). */
			uip_len = len2 + UIP_TCPIP_HLEN;
#if UIP_CONF_IPV6
			/* For IPv6, the IP length field does not include the IPv6 IP header length. */
			BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
			BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else
			BUF->len[0] = uip_len >> 8;
			BUF->len[1] = uip_len & 0xff;
#endif

			/* Sadly we must copy the packet contents down to the bottom of the packet.
			 *
			 * We know that the data sections are on a short word boundary, and not
			 * on a word boundary
			 */
			((u16_t*) uip_appdata)[0] = ((u16_t *) (uip_appdata + len1))[0];
			{
				unsigned* dst = (unsigned*) (uip_appdata + 2);
				unsigned* src = (unsigned*) (uip_appdata + 2 + len1);
				for (unsigned i = 0; i < (len2 / 4 + 1); ++i) {
					dst[i] = src[i];
				}
			}

			uip_add32(BUF->seqno, len1);
			xtcp_copy_word(BUF->seqno, uip_acc32);

			uip_split_output_send(mac_tx);
		} else {
Beispiel #4
0
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
#if UIP_TCP
  uint16_t tcplen, len1, len2;

  /* We only split TCP segments that are larger than or equal to
     UIP_SPLIT_SIZE, which is configurable through
     UIP_SPLIT_CONF_SIZE. */
  if(BUF->proto == UIP_PROTO_TCP &&
     uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {

    tcplen = uip_len - UIP_TCPIP_HLEN;
    /* Split the segment in two. If the original packet length was
       odd, we make the second packet one byte larger. */
    len1 = len2 = tcplen / 2;
    if(len1 + len2 < tcplen) {
      ++len2;
    }

    /* Create the first packet. This is done by altering the length
       field of the IP header and updating the checksums. */
    uip_len = len1 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !NETSTACK_CONF_WITH_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /* Transmit the first packet. */
    /*    uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
    tcpip_ipv6_output();
#else
    tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
   
    /* Now, create the second packet. To do this, it is not enough to
       just alter the length field, but we must also update the TCP
       sequence number and point the uip_appdata to a new place in
       memory. This place is detemined by the length of the first
       packet (len1). */
    uip_len = len2 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
    /* For IPv6, the IP length field does not include the IPv6 IP header
       length. */
    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
    BUF->len[0] = uip_len >> 8;
    BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
    
    /*    uip_appdata += len1;*/
    memcpy(uip_appdata, (uint8_t *)uip_appdata + len1, len2);

    uip_add32(BUF->seqno, len1);
    BUF->seqno[0] = uip_acc32[0];
    BUF->seqno[1] = uip_acc32[1];
    BUF->seqno[2] = uip_acc32[2];
    BUF->seqno[3] = uip_acc32[3];
    
    /* Recalculate the TCP checksum. */
    BUF->tcpchksum = 0;
    BUF->tcpchksum = ~(uip_tcpchksum());

#if !NETSTACK_CONF_WITH_IPV6
    /* Recalculate the IP checksum. */
    BUF->ipchksum = 0;
    BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */

    /* Transmit the second packet. */
    /*    uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
    tcpip_ipv6_output();
#else
    tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
    return;
  }