📄 iprouter.java
字号:
if(analyzer!=null) analyzer.reset();
//release the TCP listen port
apps.remove(new Integer((IPPacket.PRO_TCP<<16)|TCP_LISTEN_PORT));
}
public void start() {
if(sw_name_seed.getValue()==true)
randgen.setSeed(getName().hashCode());
for(int i=0;i<randgen.nextInt(100);i++) randgen.nextDouble();
double aiusec=sw_ai.getValue();
aiusec+=randgen.nextDouble()*aiusec;
theSim.enqueue(new SimEvent(EV_AVERAGING_INTERVAL,this,this,
theSim.now()+SimClock.USec2Tick(aiusec),null));
//set up a TCP listener (to sink any incoming data connections)
TCPListener listener=new TCPListener();
listener.key=sw_tcp.getTCP().open(getMyIP(),TCP_LISTEN_PORT,0,0,true,listener);
//must add an AppInfo entry for this connection
AppInfo app=new AppInfo();
app.comp=this;
app.protocol=IPPacket.PRO_TCP;
app.port=TCP_LISTEN_PORT;
apps.put(new Integer((app.protocol<<16) | app.port),app);
}
public void action(SimEvent e) {
switch(e.getType()) {
case MY_SLOT_TIME:
sw_proc_slot_time(e);
break;
case SimProvider.EV_RECEIVE:
sw_receive(e);
break;
case MY_RECEIVE:
sw_my_receive(e);
break;
case SimProvider.EV_READY:
sw_ready(e);
break;
case EV_AVERAGING_INTERVAL:
sw_averaging_interval();
theSim.enqueue(new SimEvent(EV_AVERAGING_INTERVAL,this,this,
theSim.now()+SimClock.USec2Tick(sw_ai.getValue()),null));
break;
}
}
////compInfo of IPRouter:
////(refer constant definitions near the beginning of the class declaration)
public Object compInfo(int infoid,SimComponent src,Object paramlist) {
java.util.List simparms;
java.util.Iterator i;
AppInfo app;
Object [] parms;
switch(infoid) {
case SimProvider.CI_TRANSPORT_SEND:
sw_receive_IP((IPPacket)paramlist,null);
break;
case SimProvider.CI_TRANSPORT_SEND2LINK:
parms=(Object [])paramlist;
sw_send_IP((IPPacket)parms[0],(SimComponent)parms[1]);
break;
case GET_PORT:
int newport;
int newprot=((Integer)paramlist).intValue();
do {
newport=randgen.nextInt(64512)+1024; //avoid well-known ports
} while(apps.get(new Integer((newprot<<16) | newport)) != null);
//must add an AppInfo entry
app=new AppInfo();
app.comp=src;
app.protocol=newprot;
app.port=newport;
apps.put(new Integer((newprot<<16) | newport),app);
return new Integer(newport);
case GET_PRV_PORT:
parms=(Object [])paramlist;
int theport=((Integer)parms[0]).intValue();
int theprot=((Integer)parms[1]).intValue();
if(apps.get(new Integer((theprot<<16)|theport)) != null) return null;
app=new AppInfo();
app.comp=parms[2];
app.protocol=theprot;
app.port=theport;
apps.put(new Integer((theprot<<16)|theport),app);
return new Integer(theport);
case REMOVE_PORT:
parms=(Object [])paramlist;
int oldport= ((Integer)parms[0]).intValue();
int oldprot= ((Integer)parms[1]).intValue();
apps.remove(new Integer((oldprot<<16) | oldport));
return null;
case GET_IP:
return new Integer(getMyIP());
case GET_ALL_IP:
java.util.List ips=new java.util.ArrayList();
i=voports.values().iterator();
while(i.hasNext()) {
Port voport=(Port)i.next();
ips.add(new Integer(voport.ip.getValue()));
}
return ips;
case GET_ALL_PORT:
java.util.List ports=new java.util.ArrayList();
i=apps.values().iterator();
while(i.hasNext()) {
app=(AppInfo)i.next();
ports.add(new Integer(app.port));
ports.add(new Integer(app.protocol));
}
return ports;
case ADD_ROUTE_ENTRY:
parms=(Object [])paramlist;
sw_route_table.addNewEntry(((Integer)parms[0]).intValue(),
((Integer)parms[1]).intValue(),
((Integer)parms[2]).intValue(),
(SimComponent)parms[3],(String)parms[4]);
return null;
case CLEAR_ROUTE:
sw_route_table.clearTable((String)paramlist);
return null;
case SET_PORT_IP:
parms=(Object [])paramlist;
Port voport=(Port)voports.get(parms[2]);
if(voport!=null) {
voport.ip.setValue(((Integer)parms[0]).intValue(),((Integer)parms[1]).intValue());
}
return null;
case SimProvider.CI_GET_MAC:
simparms=new java.util.ArrayList();
i=voports.values().iterator();
while(i.hasNext()) {
simparms.add(new Long(((Port)i.next()).mac_addr));
}
return simparms;
case GET_ALL_IP_LINK:
parms=(Object [])paramlist;
i=voports.values().iterator();
while(i.hasNext()) {
Port vport=(Port)i.next();
if(parms[0]!=null) ((java.util.List)parms[0]).add(vport.ip);
if(parms[1]!=null) ((java.util.List)parms[1]).add(vport.to_link);
}
return null;
}
return null;
}
////////////////////////// protected methods ////////////////////////////////
protected void sw_create() {
voports=new java.util.HashMap();
apps=new java.util.HashMap();
//Initialize the parameters
long ctick=theSim.now();
sw_delay=new SimParamDouble("Delay to process a byte (uSec)",this,ctick,false,true,0);
sw_speed=new SimParamInt("Switching Speed (Mbit/s)",this,ctick,false,true,1000);
sw_oqsize=new SimParamInt("Output q_size (kbytes, -1=inf)",this,ctick,false,true,100);
sw_red=new SimParamBool("Enable RED",this,ctick,false,true,false);
sw_red_wq=new SimParamDouble("RED queue weight (>=0.001)",this,ctick,false,true,0.002);
sw_red_minth=new SimParamInt("RED min q threshold (kbytes)",this,ctick,false,true,10);
sw_red_maxth=new SimParamInt("RED max q threshold (kbytes)",this,ctick,false,true,30);
sw_red_maxp=new SimParamDouble("RED max p (<0.1)",this,ctick,false,true,0.02);
sw_red_s=new SimParamDouble("RED s (packet trans. time) (uSec)",this,ctick,false,true,400);
sw_spqsize=new SimParamInt("Speedup q_size (kbytes, -1=inf)",this,ctick,false,true,100);
sw_ai=new SimParamDouble("Averaging Interval (usec)",this,ctick,false,true,100000.0);
sw_arp_q=new SimParamBool("Use ARP queue for IP packets",this,ctick,false,true,true);
sw_name_seed=new SimParamBool("Use name as seed",this,ctick,false,true,true);
sw_log_factor=new SimParamInt("Logging every (ticks) (e.g. 1, 100)",this,ctick,false,true,0);
sw_frames_received=new SimParamInt("Frames Received",this,ctick,true,false,0);
sw_frames_received.update(ctick);
sw_dropped=new SimParamInt("Frames Dropped (Queue)",this,ctick,true,false,0);
sw_dropped.update(ctick);
sw_dropped_clas=new SimParamInt("Frames Dropped (Classifier)",this,ctick,true,false,0);
sw_dropped_clas.update(ctick);
sw_cpucong=new SimParamBool("CPU Slow Triggered",this,ctick,true,false,false);
sw_cpucong.update(ctick);
sw_tcp=new SimParamTCP("TCP",this,ctick);
addParameter(sw_delay);
addParameter(sw_speed);
addParameter(sw_oqsize);
addParameter(sw_red);
addParameter(sw_red_wq);
addParameter(sw_red_minth);
addParameter(sw_red_maxth);
addParameter(sw_red_maxp);
addParameter(sw_red_s);
addParameter(sw_spqsize);
addParameter(sw_ai);
addParameter(sw_arp_q);
addParameter(sw_name_seed);
addParameter(sw_log_factor);
addParameter(sw_frames_received);
addParameter(sw_dropped);
addParameter(sw_dropped_clas);
addParameter(sw_cpucong);
addParameter(sw_tcp);
}
protected void sw_averaging_interval() {
//nothing here for now...
}
protected void sw_proc_slot_time(SimEvent e) {
//performing the demux_spq operation
Port voport=(Port)e.getParams();
EtherFrame frame;
long ticks;
//check for cpu congestion (just mark it, no action taken)
if(voport.spq_size > (sw_spqsize.getValue()*1024)) {
sw_cpucong.setValue(true);
sw_cpucong.update(theSim.now());
}
//voport.spq must not be empty here!
if(voport.spq.isEmpty()) {
System.out.println("Warning: sw_proc_slot_time called with spq empty!!");
return;
}
frame=(EtherFrame)voport.spq.remove(0);
voport.spq_size -= (frame.length()>>3);
if(sw_red.getValue()==true) { //whether using RED
if(voport.outQ.isEmpty()) { //q empty
double m=SimClock.Tick2USec(theSim.now()-voport.red_q_time) / sw_red_s.getValue();
voport.red_avg.setValue(Math.pow(1.0-sw_red_wq.getValue(),m) * voport.red_avg.getValue(),theSim.now(),sw_log_factor.getValue());
}
else { //q not empty
voport.red_avg.setValue(voport.red_avg.getValue()+sw_red_wq.getValue()*(voport.outQ_size.getValue()-voport.red_avg.getValue()),
theSim.now(),sw_log_factor.getValue()); //avg=(1-wq)avg + wq(q)
}
boolean mark=false;
int maxth=sw_red_maxth.getValue()<<10; //Kbyte to byte
int minth=sw_red_minth.getValue()<<10; //Kbyte to byte
if(voport.red_avg.getValue()>=maxth) { //avg >= maxth
mark=true;
voport.red_count=-1;
}
else if(voport.red_avg.getValue()>=minth) { //minth <= avg < maxth
voport.red_count++;
double pb=sw_red_maxp.getValue() * (voport.red_avg.getValue()-minth) / (maxth - minth);
pb*= (double)frame.len / EtherFrame.MAX_ETHER_LEN;
double pa=pb / (1 - voport.red_count*pb);
if(randgen.nextDouble()<pa) {
mark=true;
voport.red_count=0;
}
}
else { //avg < minth
voport.red_count=-1;
}
if(mark) {
sw_dropped.setValue(sw_dropped.getValue()+1,theSim.now(),sw_log_factor.getValue());
frame=null;
}
else if((voport.outQ_size.getValue() + (frame.length()>>3) < (sw_oqsize.getValue() << 10))
|| (sw_oqsize.getValue() == -1)) {
voport.outQ.add(frame);
voport.outQ_size.setValue(voport.outQ_size.getValue()+(frame.length() >> 3),theSim.now(),sw_log_factor.getValue());
}
else {
sw_dropped.setValue(sw_dropped.getValue()+1,theSim.now(),sw_log_factor.getValue());
frame=null;
}
}
else {
if((voport.outQ_size.getValue() + (frame.length()>>3) < (sw_oqsize.getValue() << 10))
|| (sw_oqsize.getValue() == -1)) {
voport.outQ.add(frame);
voport.outQ_size.setValue(voport.outQ_size.getValue()+(frame.length() >> 3),theSim.now(),sw_log_factor.getValue());
}
else {
sw_dropped.setValue(sw_dropped.getValue()+1,theSim.now(),sw_log_factor.getValue());
frame=null;
}
}
//output frame to link if possible
if(!voport.outQ.isEmpty() && !voport.link_busy) {
voport.link_busy=true;
sw_schedule_output(voport);
}
//schedule next proc_slot if needed
if(!voport.spq.isEmpty()) {
frame=(EtherFrame)voport.spq.get(0);
ticks=SimClock.USec2Tick(frame.length() / (double)sw_speed.getValue());
theSim.enqueue(new SimEvent(MY_SLOT_TIME,this,this,theSim.now()+ticks,voport));
}
}
protected void sw_ready(SimEvent e) {
Port voport=(Port)voports.get(e.getSource());
if(voport!=null) {
if(voport.link_busy) {
voport.link_busy=false;
if(!voport.outQ.isEmpty()) {
voport.link_busy=true;
sw_schedule_output(voport);
}
}
}
}
protected void sw_schedule_output(Port voport) {
EtherFrame frame=(EtherFrame)voport.outQ.remove(0);
voport.outQ_size.setValue(voport.outQ_size.getValue()-(frame.length()>>3),theSim.now(),sw_log_factor.getValue());
theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,
voport.to_link,theSim.now(),frame));
//RED variable
if(voport.outQ.isEmpty()) voport.red_q_time=theSim.now();
//inform analyzer
if(analyzer!=null) analyzer.update(frame,this,voport.to_link);
}
protected void sw_send_spq(EtherFrame frame,Port voport) {
voport.spq.add(frame);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -