📄 uip.lst
字号:
501 4 ++BUF->ackno[0];
502 4 }
503 3 }
504 2 }
505 1
506 1 /* Swap port numbers. */
507 1 tmpport = BUF->srcport;
508 1 BUF->srcport = BUF->destport;
509 1 BUF->destport = tmpport;
510 1
511 1 /* Swap IP addresses. */
512 1 tmpport = BUF->destipaddr[0];
513 1 BUF->destipaddr[0] = BUF->srcipaddr[0];
514 1 BUF->srcipaddr[0] = tmpport;
515 1 tmpport = BUF->destipaddr[1];
516 1 BUF->destipaddr[1] = BUF->srcipaddr[1];
517 1 BUF->srcipaddr[1] = tmpport;
518 1
519 1 /* And send out the RST packet! */
520 1 goto tcp_send_noconn;
521 1
522 1 /* This label will be jumped to if we matched the incoming packet
523 1 with a connection in LISTEN. In that case, we should create a new
524 1 connection and send a SYNACK in return. */
525 1 found_listen:
526 1 /* First we check if there are any connections avaliable. Unused
527 1 connections are kept in the same table as used connections, but
528 1 unused ones have the tcpstate set to CLOSED. */
529 1 for(c = 0; c < UIP_CONNS; ++c) {
530 2 if(uip_conns[c].tcpstateflags == CLOSED)
531 2 goto found_unused_connection;
532 2 }
533 1 for(c = 0; c < UIP_CONNS; ++c) {
534 2 if(uip_conns[c].tcpstateflags == TIME_WAIT)
535 2 goto found_unused_connection;
536 2 }
537 1 /* All connections are used already, we drop packet and hope that
538 1 the remote end will retransmit the packet at a time when we have
539 1 more spare connections. */
540 1 UIP_STAT(++uip_stat.tcp.syndrop);
541 1 UIP_LOG("tcp: found no unused connections.");
542 1 goto drop;
543 1
544 1 /* This label will be jumped to if we have found an unused
545 1 connection that we can use. */
546 1 found_unused_connection:
547 1 uip_conn = &uip_conns[c];
548 1
549 1 /* Fill in the necessary fields for the new connection. */
550 1 uip_conn->timer = UIP_RTO;
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 10
551 1 uip_conn->nrtx = 0;
552 1 uip_conn->lport = BUF->destport;
553 1 uip_conn->rport = BUF->srcport;
554 1 uip_conn->ripaddr[0] = BUF->srcipaddr[0];
555 1 uip_conn->ripaddr[1] = BUF->srcipaddr[1];
556 1 uip_conn->tcpstateflags = SYN_RCVD | UIP_OUTSTANDING;
557 1
558 1 uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0] = iss[0];
559 1 uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1] = iss[1];
560 1 uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2] = iss[2];
561 1 uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3] = iss[3];
562 1 uip_add_ack_nxt(1);
563 1
564 1 /* rcv_nxt should be the seqno from the incoming packet + 1. */
565 1 uip_conn->rcv_nxt[3] = BUF->seqno[3];
566 1 uip_conn->rcv_nxt[2] = BUF->seqno[2];
567 1 uip_conn->rcv_nxt[1] = BUF->seqno[1];
568 1 uip_conn->rcv_nxt[0] = BUF->seqno[0];
569 1 uip_add_rcv_nxt(1);
570 1
571 1
572 1 /* Parse the TCP MSS option, if present. */
573 1 if((BUF->tcpoffset & 0xf0) > 0x50) {
574 2 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
575 3 opt = uip_buf[40 + UIP_LLH_LEN + c];
576 3 if(opt == 0x00) {
577 4 /* End of options. */
578 4 break;
579 4 } else if(opt == 0x01) {
580 4 ++c;
581 4 /* NOP option. */
582 4 } else if(opt == 0x02 &&
583 3 uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
584 4 /* An MSS option with the right option length. */
585 4 tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
586 4 uip_buf[40 + UIP_LLH_LEN + c + 3];
587 4 uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
588 4
589 4 /* And we are done processing options. */
590 4 break;
591 4 } else {
592 4 /* All other options have a length field, so that we easily
593 4 can skip past them. */
594 4 c += uip_buf[40 + UIP_LLH_LEN + c + 1];
595 4 }
596 3 }
597 2 }
598 1
599 1 /* Our response will be a SYNACK. */
600 1 #if UIP_ACTIVE_OPEN
tcp_send_synack:
BUF->flags = TCP_ACK;
tcp_send_syn:
BUF->flags |= TCP_SYN;
#else /* UIP_ACTIVE_OPEN */
607 1 tcp_send_synack:
608 1 BUF->flags = TCP_SYN | TCP_ACK;
609 1 #endif /* UIP_ACTIVE_OPEN */
610 1
611 1 /* We send out the TCP Maximum Segment Size option with our
612 1 SYNACK. */
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 11
613 1 BUF->optdata[0] = 2;
614 1 BUF->optdata[1] = 4;
615 1 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
616 1 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
617 1 uip_len = 44;
618 1 BUF->tcpoffset = 6 << 4;
619 1 goto tcp_send;
620 1
621 1 /* This label will be jumped to if we found an active connection. */
622 1 found:
623 1 uip_flags = 0;
624 1
625 1 /* We do a very naive form of TCP reset processing; we just accept
626 1 any RST and kill our connection. We should in fact check if the
627 1 sequence number of this reset is wihtin our advertised window
628 1 before we accept the reset. */
629 1 if(BUF->flags & TCP_RST) {
630 2 uip_conn->tcpstateflags = CLOSED;
631 2 UIP_LOG("tcp: got reset, aborting connection.");
632 2 uip_flags = UIP_ABORT;
633 2 UIP_APPCALL();
634 2 goto drop;
635 2 }
636 1 /* All segments that are come thus far should have the ACK flag set,
637 1 otherwise we drop the packet. */
638 1 if(!(BUF->flags & TCP_ACK)) {
639 2 UIP_STAT(++uip_stat.tcp.drop);
640 2 UIP_STAT(++uip_stat.tcp.ackerr);
641 2 UIP_LOG("tcp: dropped non-ack segment.");
642 2 goto drop;
643 2 }
644 1
645 1 /* Calculated the length of the data, if the application has sent
646 1 any data to us. */
647 1 c = (BUF->tcpoffset >> 4) << 2;
648 1 /* uip_len will contain the length of the actual TCP data. This is
649 1 calculated by subtracing the length of the TCP header (in
650 1 c) and the length of the IP header (20 bytes). */
651 1 uip_len = uip_len - c - 20;
652 1
653 1 /* First, check if the sequence number of the incoming packet is
654 1 what we're expecting next. If not, we send out an ACK with the
655 1 correct numbers in. */
656 1 if(uip_len > 0 &&
657 1 (BUF->seqno[0] != uip_conn->rcv_nxt[0] ||
658 1 BUF->seqno[1] != uip_conn->rcv_nxt[1] ||
659 1 BUF->seqno[2] != uip_conn->rcv_nxt[2] ||
660 1 BUF->seqno[3] != uip_conn->rcv_nxt[3])) {
661 2 goto tcp_send_ack;
662 2 }
663 1
664 1 /* Next, check if the incoming segment acknowledges any outstanding
665 1 data. If so, we also reset the retransmission timer. */
666 1 if(BUF->ackno[0] == uip_conn->ack_nxt[0] &&
667 1 BUF->ackno[1] == uip_conn->ack_nxt[1] &&
668 1 BUF->ackno[2] == uip_conn->ack_nxt[2] &&
669 1 BUF->ackno[3] == uip_conn->ack_nxt[3]) {
670 2 uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0];
671 2 uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1];
672 2 uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2];
673 2 uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3];
674 2 if(uip_conn->tcpstateflags & UIP_OUTSTANDING) {
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 12
675 3 uip_flags = UIP_ACKDATA;
676 3 uip_conn->tcpstateflags &= ~UIP_OUTSTANDING;
677 3 uip_conn->timer = UIP_RTO;
678 3 }
679 2 }
680 1
681 1 /* Do different things depending on in what state the connection is. */
682 1 switch(uip_conn->tcpstateflags & TS_MASK) {
683 2 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
684 2 implemented, since we force the application to close when the
685 2 peer sends a FIN (hence the application goes directly from
686 2 ESTABLISHED to LAST_ACK). */
687 2 case SYN_RCVD:
688 2 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
689 2 we are waiting for an ACK that acknowledges the data we sent
690 2 out the last time. Therefore, we want to have the UIP_ACKDATA
691 2 flag set. If so, we enter the ESTABLISHED state. */
692 2 if(uip_flags & UIP_ACKDATA) {
693 3 uip_conn->tcpstateflags = ESTABLISHED;
694 3 uip_flags = UIP_CONNECTED;
695 3 uip_len = 0;
696 3 UIP_APPCALL();
697 3 goto appsend;
698 3 }
699 2 goto drop;
700 2 #if UIP_ACTIVE_OPEN
case SYN_SENT:
/* In SYN_SENT, we wait for a SYNACK that is sent in response to
our SYN. The rcv_nxt is set to sequence number in the SYNACK
plus one, and we send an ACK. We move into the ESTABLISHED
state. */
if((uip_flags & UIP_ACKDATA) &&
BUF->flags == (TCP_SYN | TCP_ACK)) {
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[40 + UIP_LLH_LEN + c];
if(opt == 0x00) {
/* End of options. */
break;
} else if(opt == 0x01) {
++c;
/* NOP option. */
} else if(opt == 0x02 &&
uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
/* An MSS option with the right option length. */
tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
uip_buf[40 + UIP_LLH_LEN + c + 3];
uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
/* And we are done processing options. */
break;
} else {
/* All other options have a length field, so that we easily
can skip past them. */
c += uip_buf[40 + UIP_LLH_LEN + c + 1];
}
}
}
uip_conn->tcpstateflags = ESTABLISHED;
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 13
uip_conn->rcv_nxt[0] = BUF->seqno[0];
uip_conn->rcv_nxt[1] = BUF->seqno[1];
uip_conn->rcv_nxt[2] = BUF->seqno[2];
uip_conn->rcv_nxt[3] = BUF->seqno[3];
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_len = 0;
UIP_APPCALL();
goto appsend;
}
goto drop;
#endif /* UIP_ACTIVE_OPEN */
749 2
750 2 case ESTABLISHED:
751 2 /* In the ESTABLISHED state, we call upon the application to feed
752 2 data into the uip_buf. If the UIP_ACKDATA flag is set, the
753 2 application should put new data into the buffer, otherwise we are
754 2 retransmitting an old segment, and the application should put that
755 2 data into the buffer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -