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

📄 tcp_subr.pc

📁 无线自组织网络的一个协议仿真软件
💻 PC
字号:
/* * GloMoSim is COPYRIGHTED software.  Release 2.02 of GloMoSim is available  * at no cost to educational users only. * * Commercial use of this software requires a separate license.  No cost, * evaluation licenses are available for such purposes; please contact * info@scalable-networks.com * * By obtaining copies of this and any other files that comprise GloMoSim2.02, * you, the Licensee, agree to abide by the following conditions and * understandings with respect to the copyrighted software: * * 1.Permission to use, copy, and modify this software and its documentation *   for education and non-commercial research purposes only is hereby granted *   to Licensee, provided that the copyright notice, the original author's *   names and unit identification, and this permission notice appear on all *   such copies, and that no charge be made for such copies. Any entity *   desiring permission to use this software for any commercial or *   non-educational research purposes should contact:  * *   Professor Rajive Bagrodia  *   University of California, Los Angeles  *   Department of Computer Science  *   Box 951596  *   3532 Boelter Hall  *   Los Angeles, CA 90095-1596  *   rajive@cs.ucla.edu * * 2.NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY *   PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * 3.Neither the software developers, the Parallel Computing Lab, UCLA, or any *   affiliate of the UC system shall be liable for any damages suffered by *   Licensee from the use of this software. */// Use the latest version of Parsec if this line causes a compiler error./* * $Id: tcp_subr.pc,v 1.9 1999/09/28 05:25:20 ktang Exp $ * * Ported from FreeBSD 2.2.2. * This file contains miscellaneous TCP subroutines, eg. initialization. *//* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 *  The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *  This product includes software developed by the University of *  California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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. * *  @(#)tcp_subr.c  8.2 (Berkeley) 5/24/95 *  $Id: tcp_subr.pc,v 1.9 1999/09/28 05:25:20 ktang Exp $ */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "api.h"#include "structmsg.h"#include "tcp.h"#include "transport.h"#include "in_pcb.h"#include "ip.h"#include "tcpip.h"#include "tcp_config.h"#include "tcp_fsm.h"#include "tcp_hdr.h"#include "tcp_proto.h"#include "tcp_seq.h"#include "tcp_timer.h"#include "tcp_var.h"#include "network.h"/* * Remove a node from reassembly queue. */voidremque_ti(node)    struct tcpiphdr *node;{    struct tcpiphdr *prev;    struct tcpiphdr *next;     next = (struct tcpiphdr *)node->ti_next;    prev = (struct tcpiphdr *)node->ti_prev;    prev->ti_next = (char *) next;    next->ti_prev = (char *) prev;} /* * Insert a node just after prev. */voidinsque_ti(node, prev)    struct tcpiphdr *node;    struct tcpiphdr *prev;{    struct tcpiphdr *next;     next = (struct tcpiphdr *)prev->ti_next;    node->ti_prev = (char *) prev;    node->ti_next = (char *) next;    prev->ti_next = (char *) node;    next->ti_prev = (char *) node;}/* * Get a new connection id. */int get_conid(head)    struct inpcb *head;{    return ++head->con_id;}/* * in_cksum -- *      Checksum routine for Internet Protocol family headers (C Version) */intin_cksum(addr, len)    unsigned short *addr;    int len;{    int nleft = len;    unsigned short *w = addr;    int sum = 0;    unsigned short answer = 0;     /*     * Our algorithm is simple, using a 32 bit accumulator (sum), we add     * sequential 16 bit words to it, and at the end, fold back all the     * carry bits from the top 16 bits into the lower 16 bits.     */    while (nleft > 1)  {        sum += *w++;        nleft -= 2;    }     /* mop up an odd byte, if necessary */    if (nleft == 1) {        *(unsigned char *)(&answer) = *(unsigned char *)w ;        sum += answer;    }     /* add back carry outs from top 16 bits to low 16 bits */    sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */    sum += (sum >> 16);                     /* add carry */    answer = ~sum;                          /* truncate to 16 bits */    return(answer);}      /* * Create template to be used to send tcp packets on a connection. * Call after host entry created, allocates an mbuf and fills * in a skeletal tcp/ip header, minimizing the amount of work * necessary when the connection is used. */struct tcpiphdr *tcp_template(tp)    struct tcpcb *tp;{    struct inpcb *inp = tp->t_inpcb;    struct tcpiphdr *n;     if ((n = tp->t_template) == 0) {        n = (struct tcpiphdr *)pc_malloc(sizeof(struct tcpiphdr));    }    assert (n != NULL);    n->ti_next = n->ti_prev = 0;    n->ti_x1 = 0;    n->ti_pr = IPPROTO_TCP;    n->ti_len = sizeof (struct tcpiphdr) - sizeof (struct ip);    n->ti_src = inp->inp_local_addr;    n->ti_dst = inp->inp_remote_addr;    n->ti_sport = inp->inp_local_port;    n->ti_dport = inp->inp_remote_port;    n->ti_seq = 0;    n->ti_ack = 0;    n->ti_x2 = 0;    n->ti_off = 5;    n->ti_flags = 0;    n->ti_win = 0;    n->ti_sum = 0;    n->ti_urp = 0;    return (n);}/* * Send a single message to the TCP at address specified by * the given TCP/IP header.  If m == 0, then we make a copy * of the tcpiphdr at ti and send directly to the addressed host. * This is used to force keep alive messages out using the TCP * template for a connection tp->t_template.  If flags are given * then we send a message back to the TCP which originated the * segment ti, and discard the mbuf containing it and any other * attached mbufs. * * In any case the ack and sequence number of the transmitted * segment are as specified by the parameters. */voidtcp_respond(node, tp, old_ti, m, ack, seq, flags, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    struct tcpiphdr *old_ti;    tcp_seq ack, seq;    int flags, m;    struct tcpstat *tcp_stat;{    int win = 0;    struct tcpiphdr *ti;    struct inpcb *inp = tp->t_inpcb;    int priority = inp->priority;    Message *msg;     if (tcp_stat != NULL) {        tcp_stat->tcps_sndtotal++;        if (flags & (TH_SYN|TH_FIN|TH_RST))            tcp_stat->tcps_sndctrl++;        else if (tp->t_flags & TF_ACKNOW)            tcp_stat->tcps_sndacks++;        else if (SEQ_GT(tp->snd_up, tp->snd_una))            tcp_stat->tcps_sndurg++;        else            tcp_stat->tcps_sndwinup++;    }    if (tp) {        win = sbspace(tp->t_inpcb);    }    msg = GLOMO_MsgAlloc(node, 0, 0, 0);    GLOMO_MsgPacketAlloc(node, msg, sizeof(struct tcpiphdr));    ti = (struct tcpiphdr *) msg->packet;    assert (ti != NULL);    memcpy(ti, old_ti, sizeof(struct tcpiphdr));    if (m == 0) {        flags = TH_ACK;    }     else {#define xchg(a,b,type) { type t; t=a; a=b; b=t; }        xchg(ti->ti_dst, ti->ti_src, unsigned long);        xchg(ti->ti_dport, ti->ti_sport, unsigned short);#undef xchg    }     ti->ti_len = (unsigned short)(sizeof (struct tcphdr));    ti->ti_next = ti->ti_prev = 0;    ti->ti_x1 = 0;    ti->ti_seq = seq;    ti->ti_ack = ack;    ti->ti_x2 = 0;    ti->ti_off = sizeof (struct tcphdr) >> 2;    ti->ti_flags = flags;    if (tp)        ti->ti_win = (unsigned short) (win >> tp->rcv_scale);    else        ti->ti_win = (unsigned short)win;    ti->ti_urp = 0;    ti->ti_sum = 0;    ti->ti_sum = in_cksum((unsigned short *)ti, sizeof (struct tcpiphdr));    ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr);     ((struct ip *)ti)->ip_ttl = IPDEFTTL;    /*    *    Send the packet and remove the extended pseudoheader so that    *    so that a real IP header can be put on at the IP Layer.      */    {         NODE_ADDR destinationAddress = ti->ti_dst;               GLOMO_MsgRemoveHeader(node, msg, sizeof(struct ipovly));        NetworkIpReceivePacketFromTransportLayer(node, msg, destinationAddress,                                                  priority,                                                  IPPROTO_TCP, TRANSPORT_DELAY);     }}/* * Create a new TCP control block, making an * empty reassembly queue and hooking it to the argument * protocol control block. */struct tcpcb *tcp_newtcpcb(inp)    struct inpcb *inp;{    struct tcpcb *tp;    tp = (struct tcpcb *)pc_malloc(sizeof(struct tcpcb));    assert(tp != NULL);    memset ((char *) tp, 0, sizeof(struct tcpcb));    tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;    tp->t_maxseg = tp->t_maxopd = TCP_MSS;    /*     * Set flags     */    if (TCP_DO_RFC1323)        tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);    if (TCP_NODELAY)        tp->t_flags |= TF_NODELAY;     if (TCP_NOOPT)        tp->t_flags |= TF_NOOPT;    if (TCP_NOPUSH)        tp->t_flags |= TF_NOPUSH;    tp->t_inpcb = inp;    /*     * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no     * rtt estimate.  Set rttvar so that srtt + 4 * rttvar gives     * reasonable initial retransmit time.     */    tp->t_srtt = TCPTV_SRTTBASE;    tp->t_rttvar = ((TCPTV_RTOBASE - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT)/4;    tp->t_rttmin = TCPTV_MIN;    tp->t_rxtcur = TCPTV_RTOBASE;    tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;    tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;    inp->inp_ppcb = (char *)tp;    return (tp);}/* * Drop a TCP connection. * If connection is synchronized, * then send a RST to peer. */struct tcpcb *tcp_drop(node, tp, tcp_now, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    unsigned long tcp_now;    struct tcpstat *tcp_stat;{    if (TCPS_HAVERCVDSYN(tp->t_state)){        tp->t_state = TCPS_CLOSED;        tcp_output(node, tp, tcp_now, tcp_stat);        if (tcp_stat)            tcp_stat->tcps_drops++;    } else {        if (tcp_stat)            tcp_stat->tcps_conndrops++;    }    return (tcp_close(node, tp, tcp_stat));}/* * Close a TCP control block: *      discard all space held by the tcp *      discard internet protocol block *      wake up any sleepers */struct tcpcb *tcp_close(node, tp, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    struct tcpstat *tcp_stat;{    struct tcpiphdr *t, *t1;    struct inpcb *inp = tp->t_inpcb;    Message *msg;    TransportToAppOpenResult *tcpOpenResult;          TransportToAppCloseResult *tcpCloseResult;    /* free the reassembly queue, if any */    t = tp->seg_next;    while (t != (struct tcpiphdr *)tp) {        t1 = t;        t = (struct tcpiphdr *)t->ti_next;        remque_ti(t1);        pc_free(t1);    }    if (tp->t_template)        pc_free(tp->t_template);    pc_free(tp);    inp->inp_ppcb = 0;    switch (inp->usrreq){    case INPCB_USRREQ_OPEN:        msg = GLOMO_MsgAlloc(node, GLOMO_APP_LAYER,                             inp->app_proto_type, MSG_APP_FromTransOpenResult);        GLOMO_MsgInfoAlloc(node, msg, sizeof(TransportToAppOpenResult));        tcpOpenResult = (TransportToAppOpenResult *) msg->info;        tcpOpenResult->type = TCP_CONN_ACTIVE_OPEN;        tcpOpenResult->localAddr = inp->inp_local_addr;        tcpOpenResult->localPort = inp->inp_local_port;        tcpOpenResult->remoteAddr = inp->inp_remote_addr;        tcpOpenResult->remotePort = inp->inp_remote_port;        tcpOpenResult->connectionId = -1;        tcpOpenResult->uniqueId = inp->unique_id;        GLOMO_MsgSend(node, msg, TRANSPORT_DELAY);         break;    case INPCB_USRREQ_CONNECTED:    case INPCB_USRREQ_CLOSE:        msg = GLOMO_MsgAlloc(node, GLOMO_APP_LAYER,                             inp->app_proto_type, MSG_APP_FromTransCloseResult);        GLOMO_MsgInfoAlloc(node, msg, sizeof(TransportToAppCloseResult));        tcpCloseResult = (TransportToAppCloseResult *) msg->info;         if (inp->usrreq == INPCB_USRREQ_CONNECTED) {            tcpCloseResult->type = TCP_CONN_PASSIVE_CLOSE;        } else {            tcpCloseResult->type = TCP_CONN_ACTIVE_CLOSE;        }        tcpCloseResult->connectionId = inp->con_id;        GLOMO_MsgSend(node, msg, TRANSPORT_DELAY);         break;    case INPCB_USRREQ_NONE: break;    default:         fprintf(stderr, "TCP: unknown user request %d\n", inp->usrreq);        assert(FALSE);    }                       in_pcbdetach(inp);    if (tcp_stat)        tcp_stat->tcps_closed++;    return ((struct tcpcb *)0);}

⌨️ 快捷键说明

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