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

📄 nettcp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************

* nettcp.c - Network Transport Control Protocol program file.

*

* Copyright (c) 1998 by Global Election Systems Inc.  All rights reserved.

*

* The authors hereby grant permission to use, copy, modify, distribute,

* and license this software and its documentation for any purpose, provided

* that existing copyright notices are retained in all copies and that this

* notice and the following disclaimer are included verbatim in any 

* distributions. No written agreement, license, or royalty fee is required

* for any of the authorized uses.

*

* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 

* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF

* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*

******************************************************************************

* REVISION HISTORY (please don't use tabs!)

*

*(yyyy-mm-dd)

* 1998-02-02 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.

*       Original based on ka9q and BSD codes.

* 2001-05-18 Mads Christiansen <mads@mogi.dk>, Partner Voxtream 

*       Added support for running uC/IP in a single proces and on ethernet.

*       Bugfix in resendTimeout, diffTime -> diffJTime!

* 2001-06-07 Robert Dickenson <odin@pnc.com.au>, Cognizant Pty Ltd.

*       Quick fix to tcpInput for when OSSemCreate hadn't been called.

*

******************************************************************************

* NOTES

*

* MAXIMUM WINDOW

*   We use a signed short int for the segment size adjustment (trimSeg()) to

* allow returning error codes.  Thus our maximum segment size must be <=

* INT_MAX (i.e. 32767) rather than MAX_UINT.  This is not a problem

* considering that we are using a PPP link over a serial link.

*

* HEADER CACHE

*   The header values are all loaded in the header caches before being

* written to the outgoing segment so that a debugger can see the values

* of the header last sent.

******************************************************************************

* TO DO

*

* - Implement a SENDFIN flag in the tcb flags and use it in tcpOutput().

* - FINISH close!

*****************************************************************************/



#include "netconf.h"

#include <string.h>

#include "net.h"

#include "nettimer.h"

#include "netbuf.h"

#if MD5_SUPPORT > 0

#include "netrand.h"

#endif

#include "netmagic.h"

//#include "devio.h"

#include "netip.h"

#include "netiphdr.h"

#include "nettcp.h"

#include "nettcphd.h"



#include <stdio.h>

#include "netdebug.h"



/*#pragma warning (push)

#pragma warning (disable: 4761) // integral size mismatch in argument; conversion supplied

#pragma warning (disable: 4018) // signed/unsigned mismatch*/



/*************************/

/*** LOCAL DEFINITIONS ***/

/*************************/

/* Configuration */

#define MAXTCP 6            /* Maximum TCP connections incl listeners. */

#define TCPTTL 64           /* Default time-to-live for TCP datagrams. */

#define OPTSPACE 5*4        /* TCP options space - must be a multiple of 4. */

#define NTCB    16          /* # TCB hash table headers */

#define MAXRETRANS 12       /* Maximum retransmissions. */

#define MAXKEEPTIMES 10     /* Maximum keep alive probe timeouts. */

#define MAXLISTEN 2         /* Maximum queued cloned listen connections. */

#define MAXFINWAIT2 600L    /* Max time in seconds to wait for peer FIN. */

#define WRITESLEEP TICKSPERSEC /* Sleep time write waits for buffers (jiffies). */

//#define STACK_SIZE NETSTACK /* Minimal stack. */





/*

 * TCP connection control flag masks.

 */

#define FORCE   1       /* We owe the other end an ACK or window update */

#define CLONE   2       /* Server-type TCB, cloned on incoming SYN */

#define RETRAN  4       /* A retransmission has occurred */

#define ACTIVE  8       /* TCB created with an active open */

#define SYNACK  16      /* Our SYN has been acked */

#define KEEPALIVE 32    /* Send a keepalive probe */



/* Round trip timing parameters */

#define AGAIN   8   /* Average RTT gain = 1/8 */

#define DGAIN   4   /* Mean deviation gain = 1/4 */

#define MSL2    30  /* Guess at two maximum-segment lifetimes in seconds */





/* procInFlags return codes. */

#define ACKOK   0       /* OK to process segment. */

#define ACKDROP -1      /* Drop the segment. */

#define ACKRESET -2     /* Return segment as a reset. */

#define ACKCLOSE -3     /* Close the connection. */





/************************/

/*** LOCAL DATA TYPES ***/

/************************/





/*

 * TCP session close reason codes.

 */

typedef enum {

    NORMAL = 0,     /* Normal close */

    RESET = 1,      /* Reset by other end */

    TIMEOUT = 2,    /* Excessive retransmissions */

    NETWORK = 3     /* Network problem (ICMP message) */

} TCPReason;











/* 

 * Shorthand for common fields.

 */

#define ipVersion   hdrCache.ipHdr.ip_v

#define ipHdrLen    hdrCache.ipHdr.ip_hl

#define ipTOS       hdrCache.ipHdr.ip_tos

#define ipLen       hdrCache.ipHdr.ip_len       /* Host byte order! */

#define ipIdent     hdrCache.ipHdr.ip_id        /* Host byte order! */

#define ipTTL       hdrCache.ipHdr.ip_ttl

#define ipProto     hdrCache.ipHdr.ip_p

#define ipSrcAddr   hdrCache.ipHdr.ip_src.s_addr /* Network byte order! */

#define ipDstAddr   hdrCache.ipHdr.ip_dst.s_addr /* Network byte order! */

#define tcpSrcPort  hdrCache.tcpHdr.srcPort     /* Network byte order! */

#define tcpDstPort  hdrCache.tcpHdr.dstPort     /* Network byte order! */

#define tcpSeq      hdrCache.tcpHdr.seq         /* Network byte order! */

#define tcpAck      hdrCache.tcpHdr.ack         /* Network byte order! */

#define tcpHdrLen   hdrCache.tcpHdr.tcpOff

#define tcpFlags    hdrCache.tcpHdr.flags

#define tcpWin      hdrCache.tcpHdr.win         /* Network byte order! */

#define tcpCkSum    hdrCache.tcpHdr.ckSum

#define tcpUrgent   hdrCache.tcpHdr.urgent      /* Network byte order! */

#define tcpOptions  hdrCache.options





/***********************************/

/*** LOCAL FUNCTION DECLARATIONS ***/

/***********************************/

#if ECHO_SUPPORT > 0

/*static void tcpEcho(void);*/

#endif

static void resendTimeout(void *arg);

static void keepTimeout(void *arg);

static void setState(TCPCB *tcb, TCPState newState);

static int procInFlags(TCPCB *tcb, TCPHdr *tcpHdr, IPHdr *ipHdr);

static void tcbInit(register TCPCB *tcb);

static void tcbUpdate(register TCPCB *tcb, register TCPHdr *tcpHdr);

static void procSyn(register TCPCB *tcb, TCPHdr *tcpHdr);

static void sendSyn(register TCPCB *tcb);

static void closeSelf(register TCPCB *tcb, int reason);

static u_int32_t newISS(void);

static void tcpOutput(TCPCB *tcb);

static u_int tcbHash(Connection *conn);

static void tcbLink(register TCPCB *tcb);

static void tcbUnlink(register TCPCB *tcb);

static TCPCB * tcbLookup(Connection *conn);

static void tcbFree(TCPCB *tcb);

static void tcpReset(

    NBuf *inBuf,                /* The input segment. */

    IPHdr *ipHdr,               /* The IP header in the segment. */

    TCPHdr *tcpHdr,             /* The TCP header in the segment. */

    u_int16_t segLen                /* The TCP segment length. */

);



static INT tcpdValid(UINT tcpd);



/*

 * trimSeg - Trim segment to fit window. 

 * Return the new segment length, -1 if segment is unaccepable.

 */

static int trimSeg(

    register TCPCB *tcb,

    register TCPHdr *tcpHdr,

    NBuf *nb,

    u_int hdrLen,

    u_int16_t segLen

);



/* 

 * backOff - Backoff function - the subject of much research.

 *

 * Use binary exponential up to retry #4, and quadratic after that

 * This yields the sequence

 * 1, 2, 4, 8, 16, 25, 36, 49, 64, 81, 100 ...

 */

#define backOff(n) ((n) <= 4 ? 1 << (n) : (n) * (n))



/* 

 * Sequence number comparisons.

 */

#define seqWithin(x, low, high) \
(((low) <= (high)) ? ((low) <= (x) && (x) <= (high)) : ((low) >= (x) && (x) >= (high)))

#define seqLT(x, y) ((long)((x) - (y)) < 0)

#define seqLE(x,y) ((long)((x) - (y)) <= 0)

#define seqGT(x,y) ((long)((x) - (y)) > 0)

#define seqGE(x,y) ((long)((x) - (y)) >= 0)



/*

 * Determine if the given sequence number is in our receiver window.

 * NB: must not be used when window is closed!

 */

#define inWindow(tcb, seq) \
    seqWithin((seq), (tcb)->rcv.nxt, (u_int32_t)((tcb)->rcv.nxt + (tcb)->rcv.wnd - 1))



/*

 * Put a data in host order into a char array in network order

 * and advance the pointer. 

 */

#define put32(cp, x) (*((u_int32 *)(cp))++ = ntohl(x))

#define put16(cp, x) (*((u_int16_t *)(cp))++ = ntohs(x))



/*

 * Operators for the cloned listen connection queue.  These should be

 * used within a critical section.

 */

#define listenQLen(tcb) \
    ((tcb)->listenQHead > (tcb)->listenQTail \
        ? (tcb)->listenQHead - (tcb)->listenQTail \
        : (tcb)->listenQTail - (tcb)->listenQHead)

#define listenQEmpty(tcb) ((tcb)->listenQHead == (tcb)->listenQTail)

#define listenQPush(tcb, ntcb) { \
    OS_ENTER_CRITICAL(); \
    if (listenQLen((tcb)) < (tcb)->listenQOpen) { \
        (tcb)->listenQ[(tcb)->listenQHead] = (ntcb); \
        (tcb)->listenQHead = ((tcb)->listenQHead + 1) % MAXLISTEN; \
    } \
    OS_EXIT_CRITICAL(); \
}

#define listenQPop(tcb, ntcbp) { \
    if ((tcb)->listenQHead != (tcb)->listenQTail) { \
        *(ntcbp) = (tcb)->listenQ[(tcb)->listenQTail]; \
        (tcb)->listenQTail = ((tcb)->listenQTail + 1) % MAXLISTEN; \
    } else \
        (ntcb) = NULL; \
}





/******************************/

/*** PUBLIC DATA STRUCTURES ***/

/******************************/

#if 0

const DevDef tcpdef = {

    tcpdValid,

    tcpdValid,

    tcpRead,

    tcpWrite,

    

    NULL,

    NULL,

    

    tcpIOCtl

};

#endif



#if STATS_SUPPORT > 0

TCPStats tcpStats;

#endif





/*****************************/

/*** LOCAL DATA STRUCTURES ***/

/*****************************/

/*

 * TCP Control block free list. 

 */

TCPCB tcbs[MAXTCP];

TCPCB *topTcpCB;                    /* Ptr to top TCB on free list. */

TCPCB *tcbTbl[NTCB];                /* Hash table for lookup. */



u_int16_t tcpFreePort = TCP_DEFPORT;    /* Initial local port. */



u_int32_t newISNOffset;                 /* Offset for the next sequence number. */





/* TCB state labels for debugging. */

char *tcbStates[] = {

    "CLOSED",

    "LISTEN",

    "SYN_SENT",

    "SYN_RECEIVED",

    "ESTABLISHED",

    "FINWAIT1",

    "FINWAIT2",

    "CLOSE_WAIT",

    "CLOSING",

    "LAST_ACK",

    "TIME_WAIT"

};



/* TCP Header Flag labels. */

#define TCPFLAGLABELMASK 0x1F       /* We don't display URGENT. */

const char *tcpFlagLabel[] = {

    "NONE",                     /* 0 */

    "FIN",                      /* 1 */

    "SYN",                      /* 2 */

    "SYN+FIN",                  /* 3 = 2 + 1 */

    "RST",                      /* 4 */

    "RST+FIN",                  /* 5 = 4 + 1 */

    "RST+SYN",                  /* 6 = 4 + 2 */

    "RST+S+F",                  /* 7 = 4 + 2 + 1 */

    "PUSH",                     /* 8 */

    "PUSH+FIN",                 /* 9 = 8 + 1 */

    "PUSH+SYN",                 /* 10 = 8 + 2 */

    "PUSH+S+F",                 /* 11 = 8 + 2 + 1 */

    "PUSH+RST",                 /* 12 = 8 + 4 */

    "PUSH+R+F",                 /* 13 = 8 + 4 + 1 */

    "PUSH+R+S",                 /* 14 = 8 + 4 + 2 */

    "PUSH+R+S+F",               /* 15 = 8 + 4 + 2 + 1 */

    "ACK",                      /* 16 */

    "ACK+FIN",                  /* 17 = 16 + 1 */

    "ACK+SYN",                  /* 18 = 16 + 2 */

    "ACK+S+F",                  /* 19 = 16 + 2 + 1 */

    "ACK+RST",                  /* 20 = 16 + 4 */

⌨️ 快捷键说明

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