📄 tcp.lst
字号:
319 1 */
320 1 /* no ack need. because this packet will give a ack to him */
321 1 pTCB->bNeedAck = FALSE;
322 1
323 1 pTCB->SeqMine += SeqInc;
324 1
325 1 /* if this packet contant data or is a FIN or SYN packet
326 1 we write it to unacked queue */
327 1 if(SeqInc != 0)
328 1 {
329 2 /* if the unacked queue is empty, start timer for this packet */
330 2 if(pTCB->QUnacked == NULL)
331 2 {
332 3 pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
333 3 pTCB->RetranTimes = 0;
334 3 }
335 2
336 2 TCPInsertQ(&(pTCB->QUnacked),MemHead,htonl(pTCPHead->Seq));
337 2 }
338 1 else
339 1 {
340 2 MemFree(MemHead);
341 2 }
342 1 return TRUE;
343 1 }
344
345 /* judge his wnd if he can receive this packet. send call TCPSendSeg.
346 only send this seg completely return TRUE*/
347 BOOL TCPSendSegJudgeWnd(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
348 {
349 1 struct SMemHead DT_XDATA *NewMemHead;
350 1
351 1 /* if WndHis is large enough to receive this packet send it.
352 1 otherwise create a new packet and send part of Data. the remain
353 1 going to transmit when WndHis refresh at TCPInput */
354 1 if(MemHead->pEnd - MemHead->pStart > pTCB->WndHis)
355 1 {
356 2 /* part of Data need send */
357 2 if(pTCB->WndHis > 0)
358 2 {
359 3 /* create a new MemHead */
360 3 if((NewMemHead = TCPAllocate(pTCB->WndHis)) == NULL)
361 3 return FALSE;
362 3
363 3 /* copy part of data to new MemHead */
364 3 MemCopy(NewMemHead->pStart,MemHead->pStart,pTCB->WndHis);
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 7
365 3
366 3 /* delete this part from old MemHead */
367 3 MemHead->pStart += pTCB->WndHis;
368 3
369 3 /* send the NewMemHead */
370 3 TCPSendSeg(pTCB,NewMemHead,TCP_ACK);
371 3
372 3 return FALSE;
373 3 }
374 2 else
375 2 {
376 3 /* can't send any data now */
377 3 return FALSE;
378 3 }
379 2 }
380 1 else
381 1 {
382 2 TCPSendSeg(pTCB,MemHead,TCP_ACK);
383 2 return TRUE;
384 2 }
385 1 }
386
387 /* send seg in unsend queue untill can't send any more. if send all
388 seg in queue return true */
389 BOOL TCPSendUnsendQ(struct STCB DT_XDATA *pTCB) REENTRANT_MUL
390 {
391 1 /* send every packet in unsend queue if can */
392 1 for(;pTCB->QUnSend != NULL;)
393 1 {
394 2 /* send it completely? */
395 2 if(TCPSendSegJudgeWnd(pTCB,pTCB->QUnSend->MemHead) == TRUE)
396 2 {
397 3 /* delete it from unsend queue */
398 3 TCPOutQ(&(pTCB->QUnSend));
399 3 }
400 2 else
401 2 {
402 3 /* only part of the seg is send */
403 3 return FALSE;
404 3 }
405 2 }
406 1 return TRUE;
407 1 }
408
409 /* call by TCPInput after judge this packet can be received.NOTE:MemHead-pStart point
410 to TCP head. TCPHead byte order is change in TCPInput */
411 void TCPRecvSeg(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_SIG
412 {
413 1 WORD TCPDataSize;
414 1 struct STCB DT_XDATA *pNewTCB;
415 1 struct SIPHead DT_XDATA *pIPHead;
416 1 struct STCPHead DT_XDATA *pTCPHead;
417 1
418 1 pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart );
419 1 pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart - IP_HEAD_MIN_LEN);
420 1
421 1 /*
422 1 * begain renew tcb values
423 1 */
424 1
425 1 /* dest windows size renew.*/
426 1 pTCB->WndHis = pTCPHead->WndSize;
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 8
427 1
428 1 /* after dest windows renew is it possible to send a packet in unsend queue now ?*/
429 1 TCPSendUnsendQ(pTCB);
430 1
431 1 /* His Sequence renew */
432 1 TCPDataSize = ntohs(pIPHead->TotalLen) - IP_HEAD_MIN_LEN
433 1 - TCP_HEAD_LEN(pTCPHead);
434 1 if((pTCPHead->flag & TCP_SYN) || (pTCPHead->flag & TCP_FIN))
435 1 {
436 2 pTCB->SeqHis += TCPDataSize + 1;
437 2 }
438 1 else
439 1 {
440 2 pTCB->SeqHis += TCPDataSize;
441 2 }
442 1
443 1 /* NeedAck? */
444 1 if(TCPDataSize != 0)
445 1 {
446 2 pTCB->bNeedAck = TRUE;
447 2 pTCB->DelayAckTimer = TCP_DELAY_ACK_TIME_OUT;
448 2 }
449 1
450 1 /* if This packet acked packet in unacked queue */
451 1 if((pTCPHead->flag & TCP_ACK) != 0)
452 1 {
453 2 while(pTCB->QUnacked != NULL &&
454 2 TCP_SEQ_COMPARE(pTCB->QUnacked->Seq,pTCPHead->AckSeq) < 0)
455 2 {
456 3 MemFree(pTCB->QUnacked->MemHead);
457 3 TCPOutQ(&(pTCB->QUnacked));
458 3
459 3 /* timer for retran restore */
460 3 pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
461 3 pTCB->RetranTimes = 0;
462 3 }
463 2 }
464 1
465 1 /*
466 1 * deal refer to tcb.state and tcp flag
467 1 */
468 1 switch(pTCB->TCPState)
469 1 {
470 2 case TCP_STATE_CLOSED:
471 2 break;
472 2 case TCP_STATE_LISTEN:
473 2 /* syn: to TCP_STATE_SYNSENT, send syn+ack */
474 2 if(pTCPHead->flag == TCP_SYN)
475 2 {
476 3 /* create a new tcb and it is going to deal with
477 3 this connection. */
478 3 if((pNewTCB = TCPSocket(htonl(pTCB->IPScr))) == NULL)
479 3 {
480 4 MemFree(MemHead);
481 4 return;
482 4 }
483 3
484 3 /* insert this tcb to tcb list isn't need. because
485 3 this tcb is already insert at TCPSocket()*/
486 3
487 3 /* initial new tcb value*/
488 3 pNewTCB->TCPState = TCP_STATE_SYNRECVD;
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 9
489 3 pNewTCB->IPDest = pIPHead->IPScr;
490 3 pNewTCB->PortDest = pTCPHead->PortScr;
491 3 pNewTCB->PortScr = pTCPHead->PortDest;
492 3
493 3 pNewTCB->SeqHis = pTCPHead->Seq + 1; /* syn is use 1
494 3 sequence */
495 3 pNewTCB->WndHis = pTCPHead->WndSize;
496 3
497 3 /* set accept function. when pNewTCB accept this
498 3 connection call pTCB->accetp */
499 3 pNewTCB->accept = pTCB->accept;
500 3
501 3 /* send syn+ack */
502 3 TCPSendSeg(pNewTCB,TCPAllocate(0),TCP_SYN | TCP_ACK);
503 3 }
504 2 break;
505 2 case TCP_STATE_SYNRECVD:
506 2
507 2 /* ack: to TCP_STATE_ESTABLISHED */
508 2 if((pTCPHead->flag & TCP_ACK) != 0)
509 2 pTCB->TCPState = TCP_STATE_ESTABLISHED;
510 2
511 2 /* call accept. Let user to know and deal more */
512 2 pTCB->accept(pTCB);
513 2
514 2 break;
515 2 case TCP_STATE_SYNSENT:
516 2 switch(pTCPHead->flag)
517 2 {
518 3 case TCP_SYN:
519 3 /* syn: to TCP_STATE_SYNRECVD send syn+ack */
520 3
521 3 pTCB->TCPState = TCP_STATE_SYNRECVD;
522 3
523 3 /* ackseq initial */
524 3 pTCB->SeqHis = pTCPHead->Seq + 1; /* syn use 1 sequence */
525 3
526 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_SYN | TCP_ACK);
527 3 break;
528 3 case TCP_SYN | TCP_ACK:
529 3 /* syn+ack: to TCP_STATE_ESTABLISHED send ack */
530 3
531 3 pTCB->TCPState = TCP_STATE_ESTABLISHED;
532 3
533 3 /* ackseq initial */
534 3 pTCB->SeqHis = pTCPHead->Seq + 1; /* syn use 1 sequence */
535 3
536 3 TCPSendSeg(pTCB,TCPAllocate(0),TCP_ACK);
537 3 break;
538 3 case TCP_RST | TCP_ACK:
539 3 /* rst: to closed */
540 3 pTCB->TCPState = TCP_STATE_CLOSED;
541 3 TCPRelease(pTCB);
542 3 break;
543 3 }
544 2 break;
545 2 case TCP_STATE_ESTABLISHED:
546 2 /* fin:to closewait send ack */
547 2 if((pTCPHead->flag & TCP_FIN) != 0)
548 2 {
549 3 pTCB->TCPState = TCP_STATE_CLOSEWAIT;
550 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 10
551 3
552 3 /* call ->close() let user to know he want to close connection
553 3 user should call TCPClose() to close the connection in ->close */
554 3 pTCB->close(pTCB);
555 3 }
556 2 break;
557 2 case TCP_STATE_CLOSEWAIT:
558 2 /* he want to close, send a fin to close */
559 2 pTCB->TCPState = TCP_STATE_LASTACK;
560 2 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT;
561 2 TCPSendSeg(pTCB,TCPAllocate(0), TCP_FIN | TCP_ACK);
562 2 break;
563 2 case TCP_STATE_FINWAIT1:
564 2 switch(pTCPHead->flag)
565 2 {
566 3 case TCP_FIN:
567 3 /* fin: to TCP_STATE_CLOSING send ack */
568 3 pTCB->TCPState = TCP_STATE_CLOSING;
569 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
570 3 break;
571 3 case TCP_FIN | TCP_ACK:
572 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
573 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
574 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
575 3 break;
576 3 case TCP_ACK:
577 3 pTCB->TCPState = TCP_STATE_FINWAIT2;
578 3 break;
579 3 }
580 2 break;
581 2 case TCP_STATE_CLOSING:
582 2 /* ack:to TCP_STATE_CLOSED */
583 2 if(pTCPHead->flag & TCP_ACK)
584 2 {
585 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
586 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
587 3 }
588 2 break;
589 2 case TCP_STATE_FINWAIT2:
590 2 if(pTCPHead->flag & TCP_FIN)
591 2 {
592 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
593 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
594 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
595 3 }
596 2 break;
597 2 }
598 1
599 1 /*
600 1 * put tcp data to uper layer
601 1 */
602 1 if(TCPDataSize != 0)
603 1 {
604 2 pTCB->recv(MemHead->pStart + TCP_HEAD_LEN(pTCPHead),TCPDataSize);
605 2 }
606 1
607 1 /*
608 1 * free this packet
609 1 */
610 1 MemFree(MemHead);
611 1 }
612
C51 COMPILER V6.12 TCP 05/19/2009 14:55:30 PAGE 11
613 /* tcp packet in.*/
614 void TCPInput(struct SMemHead DT_XDATA *MemHead) REENTRANT_SIG
615 {
616 1 struct SIPHead DT_XDATA *pIPHead;
617 1 struct STCPHead DT_XDATA *pTCPHead;
618 1 struct STCB DT_XDATA *pNewTCB;
619 1 struct STCB DT_XDATA *pTCB;
620 1
621 1 pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart);
622 1 pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart - sizeof(struct SIPHead));
623 1
624 1 /*
625 1 * is check sum ok?
626 1 */
627 1 if(TCPCheckSum(pIPHead,ntohs(pIPHead->TotalLen) - IP_HEAD_MIN_LEN) != 0)
628 1 {
629 2 MemFree(MemHead);
630 2 return;
631 2 }
632 1
633 1 /*
634 1 * is there a connection can accept this tcp packet?
635 1 */
636 1
637 1 /* if is syn packet. a tcb in listen can accept it. */
638 1 if(pTCPHead->flag == TCP_SYN)
639 1 {
640 2 for(pTCB = TCBList; pTCB != NULL; pTCB = pTCB->pNext)
641 2 {
642 3 if(pTCB->TCPState == TCP_STATE_LISTEN &&
643 3 pTCB->PortScr == pTCPHead->PortDest)
644 3 {
645 4 break;
646 4 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -