📄 tcp.lst
字号:
647 3 }
648 2 }
649 1 else
650 1 {
651 2 /* search active connections. TCBState must not the
652 2 closed and listen state */
653 2 for(pTCB = TCBList; pTCB != NULL; pTCB = pTCB->pNext)
654 2 {
655 3 /* and the source ip, dest ip, source port, dest port
656 3 must equal */
657 3 if(pTCB->PortScr == pTCPHead->PortDest &&
658 3 pTCB->PortDest == pTCPHead->PortScr &&
659 3 pTCB->TCPState != TCP_STATE_LISTEN &&
660 3 pTCB->TCPState != TCP_STATE_CLOSED &&
661 3 pTCB->IPScr == pIPHead->IPDest &&
662 3 pTCB->IPDest == pIPHead->IPScr)
663 3 break;
664 3
665 3 }
666 2 }
667 1
668 1 /* can't find, and send a rst */
669 1 if(pTCB == NULL)
670 1 {
671 2 /* allocate a temp tcb for use */
672 2 pNewTCB = TCPSocket(ntohl(pIPHead->IPDest));
673 2 pNewTCB->IPDest = pIPHead->IPScr;
674 2 pNewTCB->PortDest = pTCPHead->PortScr;
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 12
675 2 pNewTCB->PortScr = pTCPHead->PortDest;
676 2
677 2 /* set MemFree DataSize to 0 */
678 2 MemHead->pStart = MemHead->pEnd;
679 2
680 2 TCPSendSeg(pNewTCB,TCPAllocate(0),TCP_ACK | TCP_RST);
681 2
682 2 MemFree(MemHead);
683 2 TCPAbort(pNewTCB);
684 2 return;
685 2 }
686 1
687 1 /*
688 1 * is it a expected packet?
689 1 */
690 1 /* first change all necessary part to host order */
691 1 #ifndef HOST_ORDER_AS_NET
pTCPHead->AckSeq = ntohl(pTCPHead->AckSeq);
pTCPHead->Seq = ntohl(pTCPHead->Seq);
pTCPHead->WndSize = ntohs(pTCPHead->WndSize);
#endif
696 1
697 1 /* if it is the first packet from him, don't check sequence.
698 1 in connection case: a syn or syn+ack packet. in listen case
699 1 : a syn packet. so pass all packet contain syn flag */
700 1 if((pTCPHead->flag & TCP_SYN) == 0)
701 1 {
702 2 /* sequence ok? */
703 2 if(pTCB->SeqHis != pTCPHead->Seq)
704 2 {
705 3 /* if this a packet fall within rev window */
706 3 if(TCP_SEQ_COMPARE(pTCPHead->Seq,pTCB->SeqHis) > 0
707 3 && TCP_SEQ_COMPARE(pTCPHead->Seq,pTCB->SeqHis) < pTCB->WndMine)
708 3 {
709 4 /* write it to QExceedSeq for late receive */
710 4 TCPInsertQ(&(pTCB->QExceedSeq),MemHead,pTCPHead->Seq);
711 4 return;
712 4 }
713 3 else
714 3 {
715 4 /* packet fall outof window, drop it. and send a ack back, because
716 4 this is probably ocurr when our pre send ack is lose.*/
717 4 MemFree(MemHead);
718 4 TCPSendSeg(pTCB,TCPAllocate(0),TCP_ACK);
719 4 return;
720 4 }
721 3 }/* else sequence equal. ok */
722 2 }/* else is syn packet */
723 1
724 1 /* deal incoming packet */
725 1 TCPRecvSeg(pTCB,MemHead);
726 1
727 1 /* if seg in ExceedSeq can receive now? */
728 1 while(pTCB->QExceedSeq != NULL &&
729 1 pTCB->SeqHis == pTCB->QExceedSeq->Seq)
730 1 {
731 2 TCPRecvSeg(pTCB,pTCB->QExceedSeq->MemHead);
732 2 TCPOutQ(&(pTCB->QExceedSeq));
733 2 }
734 1 }
735
736 BOOL TCPSendEx(struct STCB DT_XDATA * pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 13
737 {
738 1 /* if state is "closed, listen, syn recvd, syn sent",
739 1 need connected first */
740 1 if(pTCB->TCPState <= TCP_STATE_SYNSENT)
741 1 {
742 2 MemFree(MemHead);
743 2 return FALSE;
744 2 }
745 1
746 1 /* if unsend queue is empty */
747 1 if(pTCB->QUnSend == NULL)
748 1 {
749 2 /* if this packet send completely? */
750 2 if(TCPSendSegJudgeWnd(pTCB,MemHead) == FALSE)
751 2 {
752 3 /* insert the remain for later sending */
753 3 return TCPInsertQ(&(pTCB->QUnSend),MemHead,0);
754 3 }
755 2 else
756 2 return TRUE;
757 2 }
758 1 else
759 1 return TCPInsertQ(&(pTCB->QUnSend),MemHead,0);
760 1 }
761
762 BOOL TCPSend(struct STCB DT_XDATA * pTCB,void DT_XDATA *buf,WORD DataSize) REENTRANT_MUL
763 {
764 1 struct SMemHead DT_XDATA *MemHead;
765 1
766 1 /* allocate */
767 1 if((MemHead = TCPAllocate(DataSize)) == NULL)
768 1 return FALSE;
769 1
770 1 /* copy */
771 1 MemCopy(MemHead->pStart,buf,DataSize);
772 1
773 1 return TCPSendEx(pTCB,MemHead);
774 1 }
775
776 BOOL TCPConnect(struct STCB DT_XDATA * pTCB, DWORD DestIP, WORD DestPort,
777 void (DT_CODE * recv)(void DT_XDATA * buf,WORD size) REENTRANT_MUL,
778 void (DT_CODE * close)(struct STCB DT_XDATA * pSocket) REENTRANT_MUL) REENTRANT_SIG
779 {
780 1 /* is it in closed state? */
781 1 if(pTCB->TCPState != TCP_STATE_CLOSED)
782 1 return FALSE;
783 1
784 1 /* tcb renew */
785 1 pTCB->IPDest = htonl(DestIP);
786 1 pTCB->PortDest = htons(DestPort);
787 1 pTCB->recv = recv;
788 1 pTCB->close = close;
789 1
790 1 /* send syn */
791 1 if(TCPSendSeg(pTCB,TCPAllocate(0),TCP_SYN) == TRUE)
792 1 {
793 2 pTCB->TCPState = TCP_STATE_SYNSENT;
794 2
795 2 /* wait for establish */
796 2 while(TRUE)
797 2 {
798 3 switch(pTCB->TCPState)
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 14
799 3 {
800 4 case TCP_STATE_ESTABLISHED:
801 4 return TRUE;
802 4 case TCP_STATE_CLOSED:
803 4 /* 1. if receive a rst packet from him
804 4 2. retransmittimes exceed sreshold */
805 4 return FALSE;
806 4 }
807 3 }
808 2 }
809 1 else
810 1 return FALSE;
811 1 }
812 /* call this func to innitiate closing a connection. connection
813 will not close unless peer send a fin also.*/
814 void TCPClose(struct STCB DT_XDATA *pTCB) REENTRANT_MUL
815 {
816 1 if(pTCB->TCPState != TCP_STATE_CLOSED)
817 1 {
818 2 switch(pTCB->TCPState)
819 2 {
820 3 case TCP_STATE_LISTEN:
821 3 /* close right now */
822 3 pTCB->TCPState = TCP_STATE_CLOSED;
823 3 break;
824 3 case TCP_STATE_SYNRECVD:
825 3 /* close when peer send a fin */
826 3 pTCB->TCPState = TCP_STATE_FINWAIT1;
827 3 TCPSendSeg(pTCB,TCPAllocate(0),TCP_FIN | TCP_ACK);
828 3 break;
829 3 case TCP_STATE_SYNSENT:
830 3 /* close right now */
831 3 pTCB->TCPState = TCP_STATE_CLOSED;
832 3 TCPRelease(pTCB);
833 3 break;
834 3 case TCP_STATE_ESTABLISHED:
835 3 /* close when peer send a fin */
836 3 pTCB->TCPState = TCP_STATE_FINWAIT1;
837 3 TCPSendSeg(pTCB,TCPAllocate(0),TCP_FIN | TCP_ACK);
838 3 break;
839 3 case TCP_STATE_CLOSEWAIT:
840 3 /* close when lastack time out */
841 3 pTCB->TCPState = TCP_STATE_LASTACK;
842 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT;
843 3 TCPSendSeg(pTCB,TCPAllocate(0),TCP_FIN | TCP_ACK);
844 3 break;
845 3 }
846 2 }
847 1 }
848
849 BOOL TCPListen(struct STCB DT_XDATA *pTCB,WORD ScrPort,
850 void (DT_CODE * accept)(struct STCB DT_XDATA *pNewTCB) REENTRANT_MUL) REENTRANT_MUL
851 {
852 1 struct STCB DT_XDATA *pTCBt;
853 1
854 1 /* is it in closed state? */
855 1 if(pTCB->TCPState != TCP_STATE_CLOSED)
856 1 return FALSE;
857 1
858 1 ScrPort = htons(ScrPort);
859 1
860 1 /* is there any other socket already listen in this port? */
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 15
861 1 for(pTCBt = TCBList; pTCBt != NULL; pTCBt = pTCBt->pNext)
862 1 {
863 2 if(pTCBt->PortScr == ScrPort)
864 2 return FALSE;
865 2 }
866 1
867 1 /* renew tcb */
868 1 pTCB->PortScr = ScrPort;
869 1 pTCB->TCPState = TCP_STATE_LISTEN;
870 1 pTCB->accept = accept;
871 1
872 1 return TRUE;
873 1 }
874
875 struct STCB DT_XDATA * TCPSocket(IP_ADDR ScrIP) REENTRANT_SIG
876 {
877 1 struct STCB DT_XDATA * pTCB;
878 1 struct STCB DT_XDATA * pTCBt;
879 1 WORD MaxScrPort; /* max port number in use */
880 1
881 1 /* get a tcb */
882 1 if((pTCB = TCPGetTCB()) == NULL)
883 1 {
884 2 return NULL;
885 2 }
886 1
887 1 /* allocate a scrport. that is number of
888 1 the highest number of port in use add 1 */
889 1 for(pTCBt = TCBList,MaxScrPort = TCP_DEFAULT_PORT;
890 1 pTCBt != NULL; pTCBt = pTCBt->pNext)
891 1 {
892 2 if(ntohs(pTCBt->PortScr) > MaxScrPort)
893 2 MaxScrPort = ntohs(pTCBt->PortScr);
894 2 }
895 1 pTCB->PortScr = htons((WORD)(MaxScrPort + 1));
896 1
897 1 /* other tcb set */
898 1 pTCB->TCPState = TCP_STATE_CLOSED;
899 1 pTCB->IPScr = htonl(ScrIP);
900 1 pTCB->WndMine = MemFreeSize();
901 1 pTCB->bNeedAck = FALSE;
902 1 pTCB->QExceedSeq = NULL;
903 1 pTCB->QUnacked = NULL;
904 1 pTCB->QUnSend = NULL;
905 1
906 1 /* Insert int tcb */
907 1 TCPInsertTCB(pTCB);
908 1
909 1 return pTCB;
910 1 }
911
912 /* reclaim TCB */
913 void TCPAbort(struct STCB DT_XDATA *pTCB) REENTRANT_SIG
914 {
915 1 struct STCB DT_XDATA *pTCBt;
916 1
917 1 TCPRelease(pTCB);
918 1
919 1 /*
920 1 * search through the tcb list and delete it from list
921 1 */
922 1 /* if it is the hear of the list */
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 16
923 1 if(TCBList == pTCB)
924 1 {
925 2 TCBList = TCBList->pNext;
926 2 }
927 1 else
928 1 {
929 2 /* else search start from the second one */
930 2 for(pTCBt = TCBList; pTCBt != NULL; pTCBt = pTCBt->pNext)
931 2 {
932 3 if(pTCBt->pNext == pTCB)
933 3 {
934 4 pTCBt->pNext = pTCB->pNext;
935 4 break;
936 4 }
937 3 }
938 2 }
939 1
940 1 /* reclaim it. link it to TCBFreelist */
941 1 pTCB->pNext = TCBFreeList;
942 1 TCBFreeList = pTCB;
943 1 }
944 /* this func is called by user to allocate a packet and pstart
945 point to TCPplayload */
946 struct SMemHead DT_XDATA *TCPAllocate(WORD size) REENTRANT_SIG
947 {
948 1 struct SMemHead DT_XDATA * MemHead;
949 1 if((MemHead = MemAllocate((WORD)(ALL_HEAD_SIZE + size))) == NULL)
950 1 return NULL;
951 1 else
952 1 {
953 2 /* point to the tcp data */
954 2 MemHead->pStart += ALL_HEAD_SIZE;
955 2 return MemHead;
956 2 }
957 1 }
958
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 7609 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 1476 ----
PDATA SIZE = ---- ----
DATA SIZE = ---- 28
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -