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

📄 tcp_usrreq.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_usrreq.pc,v 1.7 1999/09/28 05:25:39 ktang Exp $ * * Ported from FreeBSD 2.2.2. * This file contains TCP functions that process application requests.  *//* * Copyright (c) 1982, 1986, 1988, 1993 *  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. * *  From: @(#)tcp_usrreq.c  8.2 (Berkeley) 1/3/94 *  $Id: tcp_usrreq.pc,v 1.7 1999/09/28 05:25:39 ktang Exp $ */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "api.h"#include "main.h"#include "structmsg.h"#include "tcp.h"#include "transport.h"#include "in_pcb.h"#include "tcp_config.h"#include "tcp_fsm.h"#include "tcp_proto.h"#include "tcp_seq.h"#include "tcp_var.h"static struct tcpcb *tcp_usrclosed(GlomoNode *,                                   struct tcpcb *,                                   struct tcpstat *);/* * Prepare to accept connections. */void tcp_listen (GlomoNode *node, struct inpcb *phead, APP_TYPE app_type,                 NODE_ADDR local_addr, short local_port, int priority){    struct inpcb *inp;    int result = 0;    struct tcpcb *tp;    Message *msg;    TransportToAppListenResult *tcpListenResult;     /* check whether this server already exists */     inp = (struct inpcb *) in_pcblookup(phead,                                          local_addr,                                        local_port,                                        0,                                        0,                                        INPCB_WILDCARD);     if (inp != phead) {        result = -2;      /* listen failed, server already set up */     } else {         inp =   tcp_attach(phead,                           app_type,                           local_addr,                             local_port,                           -1,                           -1,                           -1,                           priority);        if (inp == NULL){            result = -1;  /* listen failed */        } else {            result = inp->con_id; /* listen succeeded */            tp = intotcpcb(inp);               tp->t_state = TCPS_LISTEN;        }    }    /*     * report status to application      * result = -2, server port already set up     * result = -1, failed to set up the server port     * result >= 0, succeeded     */    msg = GLOMO_MsgAlloc(node, GLOMO_APP_LAYER,                         app_type, MSG_APP_FromTransListenResult);    GLOMO_MsgInfoAlloc(node, msg, sizeof(TransportToAppListenResult));    tcpListenResult = (TransportToAppListenResult *) msg->info;    tcpListenResult->localAddr = local_addr;    tcpListenResult->localPort = local_port;    tcpListenResult->connectionId = result;        GLOMO_MsgSend(node, msg, TRANSPORT_DELAY); }/* * Do a send by putting data in output queue and * possibly send more data. */voidtcp_send(node, phead, conn_id, payload, length, tcp_now, tcp_stat)    GlomoNode *node;    struct inpcb *phead;    int conn_id;    unsigned char *payload;    int length;    unsigned long tcp_now;    struct tcpstat *tcp_stat;{    struct inpcb *inp;    struct tcpcb *tp;    inp  = in_pcbsearch(phead, conn_id);    if (inp == phead) {        /*         * can't find the in_pcb of the connection         */        fprintf(stderr, "TCP: can't find (id=%u,conn=%d)\n", node->nodeAddr,                conn_id);        assert(FALSE);    }      /*      * put data in the send buffer of the connection     * and call tcp_output to send data     */    tp = intotcpcb(inp);     length = append_buf(node, inp, payload, length);     if (length > 0){        tcp_output(node, tp, tcp_now, tcp_stat);    }}/* * Common subroutine to open a TCP connection to remote host specified * by remote_addr.   * Initialize connection parameters and enter SYN-SENT state. */void tcp_connect(GlomoNode *node, struct inpcb *phead, APP_TYPE app_type,                 NODE_ADDR local_addr, short local_port, NODE_ADDR remote_addr,                 short remote_port, unsigned long tcp_now, tcp_seq *tcp_iss,                 struct tcpstat *tcp_stat, long unique_id, int priority){    struct inpcb *inp;    int result = 0;    struct tcpcb *tp;    Message *msg;    TransportToAppOpenResult *tcpOpenResult;     /* check whether this connection already exists */     inp = (struct inpcb *) in_pcblookup(phead,                                          local_addr,                                        local_port,                                        remote_addr,                                        remote_port,                                        INPCB_NO_WILDCARD);     if (inp != phead) {        /* connection already exists */        result = -1;     } else {                                                   /* create inpcb and tcpcb for this connection */         inp  = tcp_attach(phead,                          app_type,                          local_addr,                            local_port,                          remote_addr,                          remote_port,                          unique_id,                          priority);         if (inp == NULL) {             /* can't create inpcb and tcpcb */             result = -1;           } else {             tp = intotcpcb(inp);             tp->t_template = (struct tcpiphdr *) tcp_template(tp);             if (tp->t_template == 0) {                 /* can't allocate template */                 pc_free(tp);                 inp->inp_ppcb = 0;                 in_pcbdetach(inp);                 result = -1;             }         }    }    if (result == -1) {        /*         * report failure to application and stop processing         * this message          */        msg = GLOMO_MsgAlloc(node, GLOMO_APP_LAYER,                             app_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 = result;        tcpOpenResult->uniqueId = inp->unique_id;        GLOMO_MsgSend(node, msg, TRANSPORT_DELAY);        return;    }    /*     * Set receiving window scale.     * Enter SYN_SENT state.     * Start keepalive timer and seed output sequence space.     * Send initial segment on connection.     */    while ((tp->request_r_scale < TCP_MAX_WINSHIFT) &&         ((TCP_MAXWIN << tp->request_r_scale) < inp->inp_rcv_hiwat))            tp->request_r_scale++;    tp->t_state = TCPS_SYN_SENT;    tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;    if (tcp_stat)        tcp_stat->tcps_connattempt++;    tp->iss = *tcp_iss;    *tcp_iss += TCP_ISSINCR/2;    tcp_sendseqinit(tp);    tcp_output(node, tp, tcp_now, tcp_stat);    inp->usrreq = INPCB_USRREQ_OPEN; }/* * Attach TCP protocol, allocating * internet protocol control block, tcp control block, * buffer space, initialize connection state to CLOSED.  */struct inpcb *tcp_attach (struct inpcb *head, APP_TYPE app_type,                          NODE_ADDR local_addr, short local_port,                          NODE_ADDR remote_addr, short remote_port,                          long unique_id, int priority){    struct inpcb *inp;    struct tcpcb *tp;    /*     * Create inpcb and fill in connection information     */    if ((remote_addr == -1) && (remote_port == -1)) {         /* pcb for listening port */        inp = in_pcballoc(head, 0, 0);     } else {        /* pcb for connections */         inp = in_pcballoc(head, TCP_SENDSPACE, TCP_RECVSPACE);;    }    if (inp == NULL)        return (inp);    inp->app_proto_type = app_type;    inp->inp_local_addr = local_addr;    inp->inp_local_port = local_port;    inp->inp_remote_addr = remote_addr;    inp->inp_remote_port = remote_port;    inp->con_id = get_conid(head);    inp->unique_id = unique_id;    inp->priority = priority;    /* create a tcpcb */    tp = tcp_newtcpcb(inp);    if (tp == 0){        in_pcbdetach(inp);        return (NULL);    }    tp->t_state = TCPS_CLOSED;    return (inp);}/* * Initiate (or continue) disconnect. * If embryonic state, just send reset (once). * Otherwise, switch states based on user close, and * send segment to peer (with FIN). */voidtcp_disconnect(node, phead, conn_id, tcp_now, tcp_stat)    GlomoNode *node;    struct inpcb *phead;    int conn_id;    unsigned long tcp_now;    struct tcpstat *tcp_stat;{    struct inpcb *inp;    struct tcpcb *tp;    inp  = in_pcbsearch(phead, conn_id);    if (inp == phead) {        /*         * can't find the in_pcb of the connection         */        fprintf(stderr, "TCP: can't find (id=%ld,conn=%d)\n", node->nodeAddr,                conn_id);        assert(FALSE);    }    inp->usrreq = INPCB_USRREQ_CLOSE;    tp = intotcpcb(inp);       if (tp->t_state < TCPS_ESTABLISHED)        tp = tcp_close(node, tp, tcp_stat);    else {        tp = tcp_usrclosed(node, tp, tcp_stat);        if (tp)            tcp_output(node, tp, tcp_now, tcp_stat);                           }}/* * User issued close, and wish to trail through shutdown states: * if never received SYN, just forget it.  If got a SYN from peer, * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. * If already got a FIN from peer, then almost done; go to LAST_ACK * state.  In all other cases, have already sent FIN to peer,  * and just have to play tedious game waiting * for peer to send FIN or not respond to keep-alives, etc. * We can let the user exit from the close as soon as the FIN is acked. */static struct tcpcb *tcp_usrclosed(node, tp, tcp_stat)    GlomoNode *node;    struct tcpcb *tp;    struct tcpstat *tcp_stat;{    switch (tp->t_state) {    case TCPS_CLOSED:    case TCPS_LISTEN:            tp->t_state = TCPS_CLOSED;            tp = tcp_close(node, tp, tcp_stat);            break;    case TCPS_SYN_SENT:    case TCPS_SYN_RECEIVED:            tp->t_flags |= TF_NEEDFIN;            break;    case TCPS_ESTABLISHED:            tp->t_state = TCPS_FIN_WAIT_1;            break;    case TCPS_CLOSE_WAIT:            tp->t_state = TCPS_LAST_ACK;            break;    }    if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {        /* To prevent the connection hanging in FIN_WAIT_2 forever. */        if (tp->t_state == TCPS_FIN_WAIT_2)            tp->t_timer[TCPT_2MSL] = TCPTV_MAXIDLE;    }    return (tp);}

⌨️ 快捷键说明

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