zoukankan      html  css  js  c++  java
  • ns2.35-classifier.cc

    line143:recv()

      1 /* -*-    Mode:C++; c-basic-offset:8; tab-8; indent-tabs-mode:t -*- */
      2 /*
      3  * Copyright (c) 1996 Regents of the University of California.
      4  * All rights reserved.
      5  * 
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *     This product includes software developed by the MASH Research
     17  *     Group at the University of California Berkeley.
     18  * 4. Neither the name of the University nor of the Research Group may be
     19  *    used to endorse or promote products derived from this software without
     20  *    specific prior written permission.
     21  * 
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 #ifndef lint
     36 static const char rcsid[] =
     37     "@(#) $Header: /cvsroot/nsnam/ns-2/classifier/classifier.cc,v 1.44 2010/03/08 05:54:49 tom_henderson Exp $";
     38 #endif
     39 
     40 #include <stdlib.h>
     41 #include "config.h"
     42 #include "classifier.h"
     43 #include "packet.h"
     44 #include "link/cell_header.h"
     45 
     46 static class ClassifierClass : public TclClass {
     47 public:
     48     ClassifierClass() : TclClass("Classifier") {}
     49     TclObject* create(int, const char*const*) {
     50         return (new Classifier());
     51     }
     52 } class_classifier;
     53 
     54 
     55 Classifier::Classifier() : 
     56     slot_(0), nslot_(0), maxslot_(-1), shift_(0), mask_(0xffffffff), nsize_(0)
     57 {
     58     default_target_ = 0;
     59 
     60     bind("offset_", &offset_);
     61     bind("shift_", &shift_);
     62     bind("mask_", &mask_);
     63 }
     64 
     65 int Classifier::classify(Packet *p)
     66 {
     67     return (mshift(*((int*) p->access(offset_))));
     68 }
     69 
     70 Classifier::~Classifier()
     71 {
     72     delete [] slot_;
     73 }
     74 
     75 void Classifier::set_table_size(int nn)
     76 {
     77     nsize_ = nn;
     78 }
     79 
     80 void Classifier::alloc(int slot)
     81 {
     82     NsObject** old = slot_;
     83     int n = nslot_;
     84     if (old == 0) 
     85         {    
     86         if (nsize_ != 0) {
     87             //printf("classifier %x set to %d....%dth visit
    ", this, nsize_, i++);
     88             nslot_ = nsize_;
     89         }
     90         else {
     91             //printf("classifier %x set to 32....%dth visit
    ", this, j++);
     92             nslot_ = 32;
     93         }
     94         }
     95     while (nslot_ <= slot) 
     96         nslot_ <<= 1;
     97     slot_ = new NsObject*[nslot_];
     98     memset(slot_, 0, nslot_ * sizeof(NsObject*));
     99     for (int i = 0; i < n; ++i)
    100         slot_[i] = old[i];
    101     delete [] old;
    102 }
    103 
    104 
    105 void Classifier::install(int slot, NsObject* p)
    106 {
    107     if (slot >= nslot_)
    108         alloc(slot);
    109     slot_[slot] = p;
    110     if (slot >= maxslot_)
    111         maxslot_ = slot;
    112 }
    113 
    114 void Classifier::clear(int slot)
    115 {
    116     slot_[slot] = 0;
    117     if (slot == maxslot_) {
    118         while (--maxslot_ >= 0 && slot_[maxslot_] == 0)
    119             ;
    120     }
    121 }
    122 
    123 int Classifier::allocPort (NsObject *nullagent)
    124 {
    125     return getnxt (nullagent);
    126 }
    127 
    128 int Classifier::getnxt(NsObject *nullagent)
    129 {
    130     int i;
    131     for (i=0; i < nslot_; i++)
    132         if (slot_[i]==0 || slot_[i]==nullagent)
    133             return i;
    134     i=nslot_;
    135     alloc(nslot_);
    136     return i;
    137 }
    138 
    139 /*
    140  * objects only ever see "packet" events, which come either
    141  * from an incoming link or a local agent (i.e., packet source).
    142  */
    143 void Classifier::recv(Packet* p, Handler*h)
    144 {
    145     NsObject* node = find(p);
    146     if (node == NULL) {
    147         /*
    148          * XXX this should be "dropped" somehow.  Right now,
    149          * these events aren't traced.
    150          */
    151         Packet::free(p);
    152         return;
    153     }
    154     node->recv(p,h);
    155 }
    156 
    157 /*
    158  * perform the mapping from packet to object
    159  * perform upcall if no mapping
    160  */
    161 
    162 NsObject* Classifier::find(Packet* p)
    163 {
    164     NsObject* node = NULL;
    165     int cl = classify(p);
    166     if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) { 
    167         if (default_target_) 
    168             return default_target_;
    169         /*
    170          * Sigh.  Can't pass the pkt out to tcl because it's
    171          * not an object.
    172          */
    173         Tcl::instance().evalf("%s no-slot %ld", name(), cl);
    174         if (cl == TWICE) {
    175             /*
    176              * Try again.  Maybe callback patched up the table.
    177              */
    178             cl = classify(p);
    179             if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
    180                 return (NULL);
    181         }
    182     }
    183     return (node);
    184 }
    185 
    186 int Classifier::install_next(NsObject *node) {
    187     int slot = maxslot_ + 1;
    188     install(slot, node);
    189     return (slot);
    190 }
    191 
    192 int Classifier::command(int argc, const char*const* argv)
    193 {
    194     Tcl& tcl = Tcl::instance();
    195     if(argc == 2) {
    196                 if (strcmp(argv[1], "defaulttarget") == 0) {
    197                         if (default_target_ != 0)
    198                                 tcl.result(default_target_->name());
    199                         return (TCL_OK);
    200                 }
    201         } else if (argc == 3) {
    202         /*
    203          * $classifier alloc-port nullagent
    204          */
    205         if (strcmp(argv[1],"alloc-port") == 0) {
    206             int slot;
    207             NsObject* nullagent =
    208                 (NsObject*)TclObject::lookup(argv[2]);
    209             slot = getnxt(nullagent);
    210             tcl.resultf("%u",slot);
    211             return(TCL_OK);
    212         }
    213         /*
    214          * $classifier clear $slot
    215          */
    216         if (strcmp(argv[1], "clear") == 0) {
    217             int slot = atoi(argv[2]);
    218             clear(slot);
    219             return (TCL_OK);
    220         }
    221         /*
    222          * $classifier installNext $node
    223          */
    224         if (strcmp(argv[1], "installNext") == 0) {
    225             //int slot = maxslot_ + 1;
    226             NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
    227             if (node == NULL) {
    228                 tcl.resultf("Classifier::installNext attempt "
    229             "to install non-object %s into classifier", argv[2]);
    230                 return TCL_ERROR;
    231             };
    232             int slot = install_next(node);
    233             tcl.resultf("%u", slot);
    234             return TCL_OK;
    235         }
    236         /*
    237          * $classifier slot snum
    238          * returns the name of the object in slot # snum
    239          */
    240         if (strcmp(argv[1], "slot") == 0) {
    241             int slot = atoi(argv[2]);
    242             if (slot >= 0 && slot < nslot_ && slot_[slot] != NULL) {
    243                 tcl.resultf("%s", slot_[slot]->name());
    244                 return TCL_OK;
    245             }
    246             tcl.resultf("Classifier: no object at slot %d", slot);
    247             return (TCL_ERROR);
    248         }
    249         /*
    250          * $classifier findslot $node
    251          * finds the slot containing $node
    252          */
    253         if (strcmp(argv[1], "findslot") == 0) {
    254             int slot = 0;
    255             NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
    256             if (node == NULL) {
    257                 return (TCL_ERROR);
    258             }
    259             while (slot < nslot_) {
    260                 // check if the slot is empty (xuanc, 1/14/02) 
    261                 // fix contributed by Frank A. Zdarsky 
    262                 // <frank.zdarsky@kom.tu-darmstadt.de>
    263                 if (slot_[slot] && 
    264                     strcmp(slot_[slot]->name(), argv[2]) == 0){
    265                     tcl.resultf("%u", slot);
    266                     return (TCL_OK);
    267                 }
    268                 slot++;
    269             }
    270             tcl.result("-1");
    271             return (TCL_OK);
    272         }
    273         if (strcmp(argv[1], "defaulttarget") == 0) {
    274             default_target_=(NsObject*)TclObject::lookup(argv[2]);
    275             if (default_target_ == 0)
    276                 return TCL_ERROR;
    277             return TCL_OK;
    278         }
    279     } else if (argc == 4) {
    280         /*
    281          * $classifier install $slot $node
    282          */
    283         if (strcmp(argv[1], "install") == 0) {
    284             int slot = atoi(argv[2]);
    285             NsObject* node = (NsObject*)TclObject::lookup(argv[3]);
    286             install(slot, node);
    287             return (TCL_OK);
    288         }
    289     }
    290     return (NsObject::command(argc, argv));
    291 }
    292 
    293 void Classifier::set_table_size(int, int)
    294 {}
  • 相关阅读:
    fs.mkdir
    Node Buffer 利用 slice + indexOf 生成 split 方法
    class 类
    Proxy + Reflect 实现 响应的数据变化
    ivew 封装删除 对话框
    php调用js变量
    JS调用PHP 和 PHP调用JS的方法举例
    curl远程传输工具
    php 正则只保留 汉字 字母 数字
    php 发送与接收流文件
  • 原文地址:https://www.cnblogs.com/forcheryl/p/4198699.html
Copyright © 2011-2022 走看看