KLALB3.2
This commit is contained in:
+5
-2
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/graalvm-jdk-23.0.1+11.1">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
@@ -15,11 +16,13 @@
|
||||
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-static-1.8.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/pcap4j-sample-1.8.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/JavaTUN.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-javadoc.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-tests.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
|
||||
<classpathentry kind="lib" path="lib/disruptor-4.0.0.jar" sourcepath="lib/disruptor-4.0.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/disruptor-4.0.0-javadoc.jar"/>
|
||||
<classpathentry kind="lib" path="lib/disruptor-4.0.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/JavaTUN.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
+1
-1
@@ -3,7 +3,7 @@
|
||||
"TCPListen" : "0.0.0.0:4565",
|
||||
"UDPListen" : "{UDP}0.0.0.0:4572",
|
||||
"VirtualSocketName" : "KLALB_Stream",
|
||||
"LineTable":["cn-he-plc-2.ofalias.com:4572"]
|
||||
"LineTable":["07f4acdef99b.ofalias.net:4572","{UDP}07f4acdef99b.ofalias.net:4572"]
|
||||
},
|
||||
{"Type":"SocketBridge" ,
|
||||
"Listen" : "0.0.0.0:4572",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,46 +0,0 @@
|
||||
package org.kne.acclerate;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.kne.io.Task;
|
||||
|
||||
public class FastLib {
|
||||
private static int cores=Runtime.getRuntime().availableProcessors();
|
||||
private static ExecutorService exc=Executors.newFixedThreadPool(cores,new ThreadFactory() {
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t=new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
|
||||
if(length<2000) {
|
||||
System.arraycopy(src, srcPos, dest, destPos, length);
|
||||
}else {
|
||||
int count=length/cores;
|
||||
int mod=length%cores;
|
||||
Task[]tsk=new Task[cores];
|
||||
for (int i = 0; i < cores; i++) {
|
||||
int j=i;
|
||||
Task t=new Task() {
|
||||
|
||||
@Override
|
||||
protected void runTask() {
|
||||
System.arraycopy(src, srcPos+count*j, dest, destPos+count*j, count);
|
||||
}
|
||||
};
|
||||
exc.execute(t);
|
||||
tsk[i]=t;
|
||||
}
|
||||
System.arraycopy(src, srcPos+count*cores, dest, destPos+count*cores, mod);
|
||||
for (int i = 0; i < tsk.length; i++) {
|
||||
tsk[i].waitfortask();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class ButtonSettingItem extends SettingItem {
|
||||
protected JButton button;
|
||||
|
||||
|
||||
public JButton getButton() {
|
||||
return button;
|
||||
}
|
||||
public ButtonSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public ButtonSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
button = new JButton(UIEnv.getRsb().getString("clicktoopen")+">>");
|
||||
button.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
button.setFont(button.getFont().deriveFont(Map.of(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)));
|
||||
getPanel().add(button, BorderLayout.EAST);
|
||||
button.setBorder(null);
|
||||
button.setOpaque(false);
|
||||
button.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.kne.cloud.klalb.uitool.SettingItem;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class CheckBoxSettingItem extends SettingItem {
|
||||
protected JCheckBox button;
|
||||
|
||||
|
||||
public JCheckBox getCheckBox() {
|
||||
return button;
|
||||
}
|
||||
public CheckBoxSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public CheckBoxSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
button = new JCheckBox();
|
||||
button.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
getPanel().add(button, BorderLayout.CENTER);
|
||||
button.setBorder(null);
|
||||
button.setOpaque(false);
|
||||
button.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
import javax.swing.JComboBox;
|
||||
|
||||
public class ComboSettingItem extends SettingItem {
|
||||
|
||||
|
||||
private JComboBox comboBox;
|
||||
public JComboBox getComboBox() {
|
||||
return comboBox;
|
||||
}
|
||||
public ComboSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w, h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public ComboSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
label.setForeground(Color.GRAY);
|
||||
|
||||
comboBox = new JComboBox();
|
||||
comboBox.setOpaque(false);
|
||||
getPanel().add(comboBox, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Window;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import java.awt.Label;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.TextField;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Random;
|
||||
|
||||
public class CrashReport extends JDialog{
|
||||
private JLabel name;
|
||||
private TextField type;
|
||||
private JTextArea stack;
|
||||
public CrashReport(Window parent ,boolean modal) {
|
||||
super(parent);
|
||||
setModal(modal);
|
||||
setTitle("错误");
|
||||
setIconImage(UIEnv.getIcon());
|
||||
setSize(500, 400);
|
||||
setLocationRelativeTo(null);
|
||||
stack = new JTextArea();
|
||||
stack.setEditable(false);
|
||||
getContentPane().add(new JScrollPane(stack), BorderLayout.CENTER);
|
||||
|
||||
Panel panel = new Panel();
|
||||
panel.setPreferredSize(new Dimension(500, 100));
|
||||
getContentPane().add(panel, BorderLayout.NORTH);
|
||||
panel.setLayout(null);
|
||||
|
||||
JLabel lblNewLabel = new JLabel("");
|
||||
lblNewLabel.setIcon(new ImageIcon(CrashReport.class.getResource("/assets/error.jpg")));
|
||||
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
lblNewLabel.setBounds(10, 10, 80, 80);
|
||||
panel.add(lblNewLabel);
|
||||
|
||||
name = new JLabel("");
|
||||
name.setFont(new Font("宋体", Font.PLAIN, 30));
|
||||
name.setForeground(Color.RED);
|
||||
name.setBounds(96, 10, 378, 33);
|
||||
panel.add(name);
|
||||
|
||||
type = new TextField();
|
||||
type.setEditable(false);
|
||||
type.setBounds(96, 67, 378, 23);
|
||||
panel.add(type);
|
||||
|
||||
fny = new JLabel("...?");
|
||||
fny.setFont(new Font("MS Song", Font.PLAIN, 10));
|
||||
getContentPane().add(fny, BorderLayout.SOUTH);
|
||||
}
|
||||
String []s=new String[]{"鎴戜滑鍥㈤槦鍙湁涓�涓▼搴忓憳",
|
||||
"鎯虫洿鏂帮紝娌¢棬",
|
||||
"鎴戜滑鐨勬湇鍔″櫒鐪熺殑鏄笓涓氣�滃埌瀹垛�濅簡",
|
||||
"杩炴帴宸蹭涪澶憋細涓嶅幓鍋氬惎鍔ㄥ櫒灏卞幓濂宠锛屼笉鍘诲コ瑁呭氨鍘诲仛鍚姩鍣�",
|
||||
"鍦熻眴鏈嶅姟鍣ㄥ張鍙戣娊浜�"
|
||||
};
|
||||
private JLabel fny;
|
||||
public void report(Throwable e,String t){
|
||||
e.printStackTrace();
|
||||
name.setText(t);
|
||||
type.setText(e.getClass().getName());
|
||||
StringWriter sw=new StringWriter();
|
||||
PrintWriter pw=new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
pw.close();
|
||||
stack.setText(sw.toString());fny.setText(s[new Random().nextInt(s.length)]);
|
||||
setVisible(true);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* The Metal implementation of ProgressBarUI.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Michael C. Albers
|
||||
*/
|
||||
public class KNEProgressBarUI extends BasicProgressBarUI {
|
||||
|
||||
// private Rectangle innards;
|
||||
// private Rectangle box;
|
||||
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new KNEProgressBarUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a bit of special highlighting on the progress bar.
|
||||
* The core painting is deferred to the BasicProgressBar's
|
||||
* <code>paintDeterminate</code> method.
|
||||
* @since 1.4
|
||||
*/
|
||||
public void paintDeterminate(Graphics g, JComponent c) {
|
||||
super.paintDeterminate(g,c);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a bit of special highlighting on the progress bar
|
||||
* and bouncing box.
|
||||
* The core painting is deferred to the BasicProgressBar's
|
||||
* <code>paintIndeterminate</code> method.
|
||||
* @since 1.4
|
||||
*/
|
||||
public void paintIndeterminate(Graphics g, JComponent c) {
|
||||
super.paintIndeterminate(g, c);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.ListModel;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
import java.awt.FlowLayout;
|
||||
|
||||
public abstract class ListSettingItem<T> extends SettingItem {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected JList<T> list;
|
||||
|
||||
private Consumer<T> storeRecall;
|
||||
public JList<T> getList() {
|
||||
return list;
|
||||
}
|
||||
public ListSettingItem(String text,int w,int h,XDefaultListModel<T>lm) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h,lm);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public ListSettingItem(String text, Font deriveFont,int w,int h,XDefaultListModel<T> lm) {
|
||||
super(text,deriveFont,w,h);
|
||||
list = new JList<T>(lm);
|
||||
JScrollPane js=new JScrollPane(list);
|
||||
js.getViewport().setOpaque(false);
|
||||
js.setOpaque(false);
|
||||
js.setBackground(new Color(0,0,0,0));
|
||||
getPanel().add(js, BorderLayout.CENTER);
|
||||
list.setBorder(null);
|
||||
list.setOpaque(false);
|
||||
list.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
|
||||
Dimension dss=new Dimension(25,25);
|
||||
JButton jbt3x=new JButton();
|
||||
jbt3x.setToolTipText(UIEnv.getRsb().getString("add"));
|
||||
try {
|
||||
jbt3x.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/add.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jbt3x.setSize(dss);
|
||||
jbt3x.setPreferredSize(dss);
|
||||
jbt3x.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
T x=createEmpty();
|
||||
runEdit(x);
|
||||
}
|
||||
});
|
||||
JButton jbedit=new JButton();
|
||||
jbedit.setToolTipText(UIEnv.getRsb().getString("edit"));
|
||||
try {
|
||||
jbedit.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/edit-fill.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jbedit.setSize(dss);
|
||||
jbedit.setPreferredSize(dss);
|
||||
jbedit.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
T val=list.getSelectedValue();
|
||||
if(val!=null)
|
||||
runEdit(val);
|
||||
}
|
||||
});
|
||||
|
||||
JButton jbt4x=new JButton();
|
||||
jbt4x.setToolTipText(UIEnv.getRsb().getString("remove"));
|
||||
try {
|
||||
jbt4x.setIcon(new ImageIcon(ImageIO .read(ListSettingItem.class.getResourceAsStream("/assets/delete-bin-fill.png")).getScaledInstance(dss.width-2, dss.height-2, Image.SCALE_SMOOTH)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jbt4x.setSize(dss);
|
||||
jbt4x.setPreferredSize(dss);
|
||||
jbt4x.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int v=list.getSelectedIndex();
|
||||
if(v>=0) {
|
||||
lm.remove(v);
|
||||
if(storeRecall!=null)
|
||||
storeRecall.accept(list.getSelectedValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
JPanel jp=new JPanel();
|
||||
jp.setPreferredSize(new Dimension(30, h));
|
||||
FlowLayout flowLayout = (FlowLayout) jp.getLayout();
|
||||
flowLayout.setAlignment(FlowLayout.TRAILING);
|
||||
jp.setOpaque(false);
|
||||
getPanel().add(jp,BorderLayout.EAST);
|
||||
jp.add(jbt3x);
|
||||
jp.add(jbedit);
|
||||
jp.add(jbt4x);
|
||||
}
|
||||
abstract protected void runEdit(T val) ;
|
||||
abstract protected T createEmpty() ;
|
||||
public void doAdd(T v) {
|
||||
boolean b=true;
|
||||
for (int i = 0; i < list.getModel().getSize(); i++) {
|
||||
if(list.getModel().getElementAt(i)==v) {
|
||||
b=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(b)
|
||||
((XDefaultListModel<T>) list.getModel()).addElement(v);
|
||||
repaint();
|
||||
if(storeRecall!=null)
|
||||
storeRecall.accept(list.getSelectedValue());
|
||||
}
|
||||
public Consumer<T> getStoreRecall() {
|
||||
return storeRecall;
|
||||
}
|
||||
public void setStoreRecall(Consumer<T> storeRecall) {
|
||||
this.storeRecall = storeRecall;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import javax.swing.*;
|
||||
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class PathInput extends JDialog {
|
||||
private JTextField textField;
|
||||
private boolean checkfile=true;
|
||||
private boolean isdir=false;
|
||||
protected JFileChooser jfc;
|
||||
private Consumer<File> al;
|
||||
public Consumer<File> getAl() {
|
||||
return al;
|
||||
}
|
||||
|
||||
public void setAl(Consumer<File> al) {
|
||||
this.al = al;
|
||||
}
|
||||
|
||||
public PathInput(Window d){
|
||||
super(d);
|
||||
setResizable(false);
|
||||
setModal(true);
|
||||
setSize(500, 110);
|
||||
setLocationRelativeTo(d);
|
||||
|
||||
setIconImage(UIEnv.getIcon());
|
||||
|
||||
textField = new JTextField();
|
||||
textField.setPreferredSize(new Dimension(400,80));
|
||||
textField.setFont(new Font("微软雅黑", Font.PLAIN, 12));
|
||||
getContentPane().add(textField, BorderLayout.CENTER);
|
||||
textField.setColumns(10);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
getContentPane().add(panel, BorderLayout.SOUTH);
|
||||
|
||||
JButton btnok = new JButton(UIEnv.getRsb().getString("ok"));
|
||||
UIEnv.defbut(btnok);
|
||||
panel.add(btnok);
|
||||
btnok.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
File x=new File(textField.getText());
|
||||
if(!checkfile){
|
||||
if(isdir){
|
||||
x.mkdirs();
|
||||
}else{
|
||||
try {
|
||||
x.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
al.accept(x);
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
if(x.exists()){
|
||||
al.accept(x);
|
||||
setVisible(false);
|
||||
}else{
|
||||
JOptionPane.showMessageDialog(PathInput.this, UIEnv.getRsb().getString("filenotexist"), UIEnv.getRsb().getString("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
JButton btnNewButton_1 = new JButton(UIEnv.getRsb().getString("browse"));
|
||||
UIEnv.defbut(btnNewButton_1);
|
||||
panel.add(btnNewButton_1);
|
||||
btnNewButton_1.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(jfc.showOpenDialog(PathInput.this)==jfc.APPROVE_OPTION){
|
||||
textField.setText(jfc.getSelectedFile().toString());
|
||||
}
|
||||
/*File f=choose.get();
|
||||
if(f!=null){
|
||||
textField.setText(f.toString());
|
||||
}*/
|
||||
}
|
||||
});
|
||||
JButton button = new JButton(UIEnv.getRsb().getString("cancel"));
|
||||
UIEnv.defbut(button);
|
||||
panel.add(button);
|
||||
button.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
jfc=new JFileChooser();
|
||||
jfc.setMultiSelectionEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
public JTextField getTextField() {
|
||||
return textField;
|
||||
}
|
||||
|
||||
public JFileChooser getJfc() {
|
||||
return jfc;
|
||||
}
|
||||
|
||||
public boolean isCheckfile() {
|
||||
return checkfile;
|
||||
}
|
||||
public void setCheckfile(boolean checkfile) {
|
||||
this.checkfile = checkfile;
|
||||
}
|
||||
public boolean isIsdir() {
|
||||
return isdir;
|
||||
}
|
||||
public void setIsdir(boolean isdir) {
|
||||
this.isdir = isdir;
|
||||
if(isdir) {
|
||||
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
}else {
|
||||
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.kne.cloud.klalb.uitool.SettingItem;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class RadioButtonSettingItem extends SettingItem {
|
||||
protected JRadioButton button;
|
||||
|
||||
|
||||
public JRadioButton getRadioButton() {
|
||||
return button;
|
||||
}
|
||||
public RadioButtonSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public RadioButtonSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
button = new JRadioButton();
|
||||
button.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
getPanel().add(button, BorderLayout.CENTER);
|
||||
button.setBorder(null);
|
||||
button.setOpaque(false);
|
||||
button.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import javax.swing.SpringLayout;
|
||||
|
||||
public class SettingItem extends JPanel {
|
||||
protected JLabel label;
|
||||
private JPanel sub;
|
||||
|
||||
public JLabel getLabel() {
|
||||
return label;
|
||||
}
|
||||
public SettingItem(String text,int w,int h){
|
||||
this(text,UIEnv.getFont().deriveFont(15.0f),w,h);
|
||||
}
|
||||
public JPanel getPanel(){
|
||||
return sub;
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public SettingItem(String text,Font f,int w,int h){
|
||||
setSize(w, h);
|
||||
setPreferredSize(new Dimension(w, h));
|
||||
setBackground(UIEnv.getHalfTransparentDefaultColor());
|
||||
SpringLayout springLayout = new SpringLayout();
|
||||
setLayout(springLayout);
|
||||
//setOpaque(false);
|
||||
sub = new JPanel();
|
||||
springLayout.putConstraint(SpringLayout.NORTH, sub, 0, SpringLayout.NORTH, this);
|
||||
springLayout.putConstraint(SpringLayout.WEST, sub, 20, SpringLayout.WEST, this);
|
||||
springLayout.putConstraint(SpringLayout.SOUTH, sub, 0, SpringLayout.SOUTH, this);
|
||||
springLayout.putConstraint(SpringLayout.EAST, sub, -20, SpringLayout.EAST, this);
|
||||
sub.setOpaque(false);
|
||||
add(sub);
|
||||
sub.setLayout(new BorderLayout(5, 0));
|
||||
label = new JLabel(text);
|
||||
label.setFont(f);
|
||||
sub.add(label, BorderLayout.WEST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class TextAreaSettingItem extends SettingItem {
|
||||
protected JTextArea textarea;
|
||||
|
||||
|
||||
public JTextArea getTextArea() {
|
||||
return textarea;
|
||||
}
|
||||
public TextAreaSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public TextAreaSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
textarea = new JTextArea();
|
||||
JScrollPane sp=new JScrollPane(textarea);
|
||||
sp.getViewport().setOpaque(false);
|
||||
sp.setOpaque(false);
|
||||
sp.setBackground(new Color(0,0,0,0));
|
||||
getPanel().add(sp, BorderLayout.CENTER);
|
||||
textarea.setBorder(null);
|
||||
textarea.setOpaque(false);
|
||||
textarea.setBackground(new Color(0,0,0,0));
|
||||
//textarea.setBackground(UIEnv.getDefaultcolor());
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class TextButtonSettingItem extends SettingItem {
|
||||
protected JTextField textField;
|
||||
protected JButton button;
|
||||
|
||||
public JButton getButton() {
|
||||
return button;
|
||||
}
|
||||
public JTextField getTextField() {
|
||||
return textField;
|
||||
}
|
||||
public TextButtonSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public TextButtonSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
BorderLayout borderLayout = (BorderLayout) getPanel().getLayout();
|
||||
textField = new JTextField();
|
||||
textField.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
getPanel().add(textField, BorderLayout.CENTER);
|
||||
textField.setColumns(10);
|
||||
textField.setBorder(null);
|
||||
textField.setOpaque(false);
|
||||
textField.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
|
||||
button = new JButton();
|
||||
getPanel().add(button, BorderLayout.EAST);
|
||||
button.setFont(button.getFont().deriveFont(Map.of(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)));
|
||||
button.setBorder(null);
|
||||
button.setOpaque(false);
|
||||
button.setBackground(new Color(0,0,0,0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
|
||||
public class TextSettingItem extends SettingItem {
|
||||
protected JTextField textField;
|
||||
|
||||
|
||||
public JTextField getTextField() {
|
||||
return textField;
|
||||
}
|
||||
public TextSettingItem(String text,int w,int h) {
|
||||
this(text,UIEnv.getFont().deriveFont((float) 15.0),w,h);
|
||||
}
|
||||
/**
|
||||
* @wbp.parser.constructor
|
||||
*/
|
||||
public TextSettingItem(String text, Font deriveFont,int w,int h) {
|
||||
super(text,deriveFont,w,h);
|
||||
textField = new JTextField();
|
||||
textField.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
getPanel().add(textField, BorderLayout.CENTER);
|
||||
textField.setColumns(10);
|
||||
textField.setBorder(null);
|
||||
textField.setOpaque(false);
|
||||
textField.setBackground(new Color(0,0,0,0));
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* The abstract definition for the data model that provides
|
||||
* a <code>List</code> with its contents.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @since 1.2
|
||||
*/
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
public abstract class XAbstractListModel<E> implements ListModel<E>, Serializable
|
||||
{
|
||||
/**
|
||||
* The listener list.
|
||||
*/
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
protected XAbstractListModel() {}
|
||||
|
||||
/**
|
||||
* Adds a listener to the list that's notified each time a change
|
||||
* to the data model occurs.
|
||||
*
|
||||
* @param l the <code>ListDataListener</code> to be added
|
||||
*/
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
listenerList.add(ListDataListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a listener from the list that's notified each time a
|
||||
* change to the data model occurs.
|
||||
*
|
||||
* @param l the <code>ListDataListener</code> to be removed
|
||||
*/
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
listenerList.remove(ListDataListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the list data listeners
|
||||
* registered on this <code>AbstractListModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ListDataListener</code>s,
|
||||
* or an empty array if no list data listeners
|
||||
* are currently registered
|
||||
*
|
||||
* @see #addListDataListener
|
||||
* @see #removeListDataListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ListDataListener[] getListDataListeners() {
|
||||
return listenerList.getListeners(ListDataListener.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b>
|
||||
* one or more elements of the list change. The changed elements
|
||||
* are specified by the closed interval index0, index1 -- the endpoints
|
||||
* are included. Note that
|
||||
* index0 need not be less than or equal to index1.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the new interval
|
||||
* @param index1 the other end of the new interval
|
||||
* @see EventListenerList
|
||||
* @see XDefaultListModel
|
||||
*/
|
||||
protected void fireContentsChanged(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).contentsChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b>
|
||||
* one or more elements are added to the model. The new elements
|
||||
* are specified by a closed interval index0, index1 -- the enpoints
|
||||
* are included. Note that
|
||||
* index0 need not be less than or equal to index1.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the new interval
|
||||
* @param index1 the other end of the new interval
|
||||
* @see EventListenerList
|
||||
* @see XDefaultListModel
|
||||
*/
|
||||
protected void fireIntervalAdded(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).intervalAdded(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b> one or more elements are removed from the model.
|
||||
* <code>index0</code> and <code>index1</code> are the end points
|
||||
* of the interval that's been removed. Note that <code>index0</code>
|
||||
* need not be less than or equal to <code>index1</code>.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the removed interval,
|
||||
* including <code>index0</code>
|
||||
* @param index1 the other end of the removed interval,
|
||||
* including <code>index1</code>
|
||||
* @see EventListenerList
|
||||
* @see XDefaultListModel
|
||||
*/
|
||||
protected void fireIntervalRemoved(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).intervalRemoved(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a list model
|
||||
* <code>m</code>
|
||||
* for its list data listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ListDataListener[] ldls = (ListDataListener[])(m.getListeners(ListDataListener.class));</pre>
|
||||
*
|
||||
* If no such listeners exist,
|
||||
* this method returns an empty array.
|
||||
*
|
||||
* @param <T> the type of {@code EventListener} class being requested
|
||||
* @param listenerType the type of listeners requested;
|
||||
* this parameter should specify an interface
|
||||
* that descends from <code>java.util.EventListener</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getListDataListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
|
||||
public class XButton extends JButton{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public XButton() {
|
||||
super();
|
||||
super.setContentAreaFilled(false);
|
||||
}
|
||||
|
||||
public XButton(Action a) {
|
||||
super(a);
|
||||
super.setContentAreaFilled(false);
|
||||
}
|
||||
|
||||
public XButton(Icon icon) {
|
||||
super(icon);
|
||||
super.setContentAreaFilled(false);
|
||||
}
|
||||
|
||||
public XButton(String text, Icon icon) {
|
||||
super(text, icon);
|
||||
super.setContentAreaFilled(false);
|
||||
}
|
||||
|
||||
public XButton(String text) {
|
||||
super(text);
|
||||
super.setContentAreaFilled(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(getBackground());
|
||||
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.kne.cloud.klalb.uitool;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
|
||||
|
||||
/**
|
||||
* This class loosely implements the {@code java.util.Vector}
|
||||
* API, in that it implements the 1.1.x version of
|
||||
* {@code java.util.Vector}, has no collection class support,
|
||||
* and notifies the {@code ListDataListener}s when changes occur.
|
||||
* Presently it delegates to a {@code Vector},
|
||||
* in a future release it will be a real Collection implementation.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans
|
||||
* has been added to the {@code java.beans} package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @since 1.2
|
||||
*/
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
public class XDefaultListModel<E> extends XAbstractListModel<E> implements Externalizable
|
||||
{
|
||||
private Vector<E> delegate = new Vector<E>();
|
||||
|
||||
/**
|
||||
* Constructs a {@code DefaultListModel}.
|
||||
*/
|
||||
public XDefaultListModel() {}
|
||||
|
||||
/**
|
||||
* Returns the number of components in this list.
|
||||
* <p>
|
||||
* This method is identical to {@code size}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* This method exists in conjunction with {@code setSize} so that
|
||||
* {@code size} is identifiable as a JavaBean property.
|
||||
*
|
||||
* @return the number of components in this list
|
||||
* @see #size()
|
||||
*/
|
||||
public int getSize() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code get(int)}, which implements the {@code List}
|
||||
* interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
* @param index an index into this list
|
||||
* @return the component at the specified index
|
||||
* @throws ArrayIndexOutOfBoundsException if the {@code index}
|
||||
* is negative or greater than the current size of this
|
||||
* list
|
||||
* @see #get(int)
|
||||
*/
|
||||
public E getElementAt(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the components of this list into the specified array.
|
||||
* The array must be big enough to hold all the objects in this list,
|
||||
* else an {@code IndexOutOfBoundsException} is thrown.
|
||||
*
|
||||
* @param anArray the array into which the components get copied
|
||||
* @see Vector#copyInto(Object[])
|
||||
*/
|
||||
public void copyInto(Object[] anArray) {
|
||||
delegate.copyInto(anArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the capacity of this list to be the list's current size.
|
||||
*
|
||||
* @see Vector#trimToSize()
|
||||
*/
|
||||
public void trimToSize() {
|
||||
delegate.trimToSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the capacity of this list, if necessary, to ensure
|
||||
* that it can hold at least the number of components specified by
|
||||
* the minimum capacity argument.
|
||||
*
|
||||
* @param minCapacity the desired minimum capacity
|
||||
* @see Vector#ensureCapacity(int)
|
||||
*/
|
||||
public void ensureCapacity(int minCapacity) {
|
||||
delegate.ensureCapacity(minCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of this list.
|
||||
*
|
||||
* @param newSize the new size of this list
|
||||
* @see Vector#setSize(int)
|
||||
*/
|
||||
public void setSize(int newSize) {
|
||||
int oldSize = delegate.size();
|
||||
delegate.setSize(newSize);
|
||||
if (oldSize > newSize) {
|
||||
fireIntervalRemoved(this, newSize, oldSize-1);
|
||||
}
|
||||
else if (oldSize < newSize) {
|
||||
fireIntervalAdded(this, oldSize, newSize-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current capacity of this list.
|
||||
*
|
||||
* @return the current capacity
|
||||
* @see Vector#capacity()
|
||||
*/
|
||||
public int capacity() {
|
||||
return delegate.capacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of components in this list.
|
||||
*
|
||||
* @return the number of components in this list
|
||||
* @see Vector#size()
|
||||
*/
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this list has any components.
|
||||
*
|
||||
* @return {@code true} if and only if this list has
|
||||
* no components, that is, its size is zero;
|
||||
* {@code false} otherwise
|
||||
* @see Vector#isEmpty()
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return delegate.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the components of this list.
|
||||
*
|
||||
* @return an enumeration of the components of this list
|
||||
* @see Vector#elements()
|
||||
*/
|
||||
public Enumeration<E> elements() {
|
||||
return delegate.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the specified object is a component in this list.
|
||||
*
|
||||
* @param elem an object
|
||||
* @return {@code true} if the specified object
|
||||
* is the same as a component in this list
|
||||
* @see Vector#contains(Object)
|
||||
*/
|
||||
public boolean contains(Object elem) {
|
||||
return delegate.contains(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the first occurrence of {@code elem}.
|
||||
*
|
||||
* @param elem an object
|
||||
* @return the index of the first occurrence of the argument in this
|
||||
* list; returns {@code -1} if the object is not found
|
||||
* @see Vector#indexOf(Object)
|
||||
*/
|
||||
public int indexOf(Object elem) {
|
||||
return delegate.indexOf(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the first occurrence of {@code elem}, beginning
|
||||
* the search at {@code index}.
|
||||
*
|
||||
* @param elem the desired component
|
||||
* @param index the index from which to begin searching
|
||||
* @return the index where the first occurrence of {@code elem}
|
||||
* is found after {@code index}; returns {@code -1}
|
||||
* if the {@code elem} is not found in the list
|
||||
* @see Vector#indexOf(Object,int)
|
||||
*/
|
||||
public int indexOf(Object elem, int index) {
|
||||
return delegate.indexOf(elem, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of {@code elem}.
|
||||
*
|
||||
* @param elem the desired component
|
||||
* @return the index of the last occurrence of {@code elem}
|
||||
* in the list; returns {@code elem} if the object is not found
|
||||
* @see Vector#lastIndexOf(Object)
|
||||
*/
|
||||
public int lastIndexOf(Object elem) {
|
||||
return delegate.lastIndexOf(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches backwards for {@code elem}, starting from the
|
||||
* specified index, and returns an index to it.
|
||||
*
|
||||
* @param elem the desired component
|
||||
* @param index the index to start searching from
|
||||
* @return the index of the last occurrence of the {@code elem}
|
||||
* in this list at position less than {@code index};
|
||||
* returns {@code -1} if the object is not found
|
||||
* @see Vector#lastIndexOf(Object,int)
|
||||
*/
|
||||
public int lastIndexOf(Object elem, int index) {
|
||||
return delegate.lastIndexOf(elem, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code get(int)}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param index an index into this list
|
||||
* @return the component at the specified index
|
||||
* @throws ArrayIndexOutOfBoundsException if the index
|
||||
* is negative or not less than the size of the list
|
||||
* @see #get(int)
|
||||
* @see Vector#elementAt(int)
|
||||
*/
|
||||
public E elementAt(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first component of this list.
|
||||
* @return the first component of this list
|
||||
* @see Vector#firstElement()
|
||||
* @throws java.util.NoSuchElementException if this
|
||||
* vector has no components
|
||||
*/
|
||||
public E firstElement() {
|
||||
return delegate.firstElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last component of the list.
|
||||
*
|
||||
* @return the last component of the list
|
||||
* @see Vector#lastElement()
|
||||
* @throws java.util.NoSuchElementException if this vector
|
||||
* has no components
|
||||
*/
|
||||
public E lastElement() {
|
||||
return delegate.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the component at the specified {@code index} of this
|
||||
* list to be the specified element. The previous component at that
|
||||
* position is discarded.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code set(int,Object)}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param element what the component is to be set to
|
||||
* @param index the specified index
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is invalid
|
||||
* @see #set(int,Object)
|
||||
* @see Vector#setElementAt(Object,int)
|
||||
*/
|
||||
public void setElementAt(E element, int index) {
|
||||
delegate.setElementAt(element, index);
|
||||
fireContentsChanged(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the component at the specified index.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code remove(int)}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param index the index of the object to remove
|
||||
* @see #remove(int)
|
||||
* @see Vector#removeElementAt(int)
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is invalid
|
||||
*/
|
||||
public void removeElementAt(int index) {
|
||||
delegate.removeElementAt(index);
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element as a component in this list at the
|
||||
* specified <code>index</code>.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code add(int,Object)}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param element the component to insert
|
||||
* @param index where to insert the new component
|
||||
* @exception ArrayIndexOutOfBoundsException if the index was invalid
|
||||
* @see #add(int,Object)
|
||||
* @see Vector#insertElementAt(Object,int)
|
||||
*/
|
||||
public void insertElementAt(E element, int index) {
|
||||
delegate.insertElementAt(element, index);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified component to the end of this list.
|
||||
*
|
||||
* @param element the component to be added
|
||||
* @see Vector#addElement(Object)
|
||||
*/
|
||||
public void addElement(E element) {
|
||||
int index = delegate.size();
|
||||
delegate.addElement(element);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first (lowest-indexed) occurrence of the argument
|
||||
* from this list.
|
||||
*
|
||||
* @param obj the component to be removed
|
||||
* @return {@code true} if the argument was a component of this
|
||||
* list; {@code false} otherwise
|
||||
* @see Vector#removeElement(Object)
|
||||
*/
|
||||
public boolean removeElement(Object obj) {
|
||||
int index = indexOf(obj);
|
||||
boolean rv = delegate.removeElement(obj);
|
||||
if (index >= 0) {
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all components from this list and sets its size to zero.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is {@code clear}, which implements the
|
||||
* {@code List} interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @see #clear()
|
||||
* @see Vector#removeAllElements()
|
||||
*/
|
||||
public void removeAllElements() {
|
||||
int index1 = delegate.size()-1;
|
||||
delegate.removeAllElements();
|
||||
if (index1 >= 0) {
|
||||
fireIntervalRemoved(this, 0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that displays and identifies this
|
||||
* object's properties.
|
||||
*
|
||||
* @return a String representation of this object
|
||||
*/
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
|
||||
/* The remaining methods are included for compatibility with the
|
||||
* Java 2 platform Vector class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in the
|
||||
* correct order.
|
||||
*
|
||||
* @return an array containing the elements of the list
|
||||
* @see Vector#toArray()
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
Object[] rv = new Object[delegate.size()];
|
||||
delegate.copyInto(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element at the specified position in this list.
|
||||
*
|
||||
* @param index index of element to return
|
||||
* @return the element at the specified position in this list
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is out of range
|
||||
* ({@code index < 0 || index >= size()})
|
||||
*/
|
||||
public E get(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the
|
||||
* specified element.
|
||||
*
|
||||
* @param index index of element to replace
|
||||
* @param element element to be stored at the specified position
|
||||
* @return the element previously at the specified position
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is out of range
|
||||
* ({@code index < 0 || index >= size()})
|
||||
*/
|
||||
public E set(int index, E element) {
|
||||
E rv = delegate.elementAt(index);
|
||||
delegate.setElementAt(element, index);
|
||||
fireContentsChanged(this, index, index);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the specified position in this list.
|
||||
*
|
||||
* @param index index at which the specified element is to be inserted
|
||||
* @param element element to be inserted
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is out of range
|
||||
* ({@code index < 0 || index > size()})
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
delegate.insertElementAt(element, index);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list.
|
||||
* Returns the element that was removed from the list
|
||||
*
|
||||
* @param index the index of the element to removed
|
||||
* @return the element previously at the specified position
|
||||
* @throws ArrayIndexOutOfBoundsException if the index is out of range
|
||||
* ({@code index < 0 || index >= size()})
|
||||
*/
|
||||
public E remove(int index) {
|
||||
E rv = delegate.elementAt(index);
|
||||
delegate.removeElementAt(index);
|
||||
fireIntervalRemoved(this, index, index);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this list. The list will
|
||||
* be empty after this call returns (unless it throws an exception).
|
||||
*/
|
||||
public void clear() {
|
||||
int index1 = delegate.size()-1;
|
||||
delegate.removeAllElements();
|
||||
if (index1 >= 0) {
|
||||
fireIntervalRemoved(this, 0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the components at the specified range of indexes.
|
||||
* The removal is inclusive, so specifying a range of (1,5)
|
||||
* removes the component at index 1 and the component at index 5,
|
||||
* as well as all components in between.
|
||||
*
|
||||
* @param fromIndex the index of the lower end of the range
|
||||
* @param toIndex the index of the upper end of the range
|
||||
* @throws ArrayIndexOutOfBoundsException if the index was invalid
|
||||
* @throws IllegalArgumentException if {@code fromIndex > toIndex}
|
||||
* @see #remove(int)
|
||||
*/
|
||||
public void removeRange(int fromIndex, int toIndex) {
|
||||
if (fromIndex > toIndex) {
|
||||
throw new IllegalArgumentException("fromIndex must be <= toIndex");
|
||||
}
|
||||
for(int i = toIndex; i >= fromIndex; i--) {
|
||||
delegate.removeElementAt(i);
|
||||
}
|
||||
fireIntervalRemoved(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements present in the collection to the list.
|
||||
*
|
||||
* @param c the collection which contains the elements to add
|
||||
* @throws NullPointerException if {@code c} is null
|
||||
*/
|
||||
public void addAll(Collection<? extends E> c) {
|
||||
if (c.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int startIndex = getSize();
|
||||
|
||||
delegate.addAll(c);
|
||||
fireIntervalAdded(this, startIndex, getSize() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements present in the collection, starting
|
||||
* from the specified index.
|
||||
*
|
||||
* @param index index at which to insert the first element from the
|
||||
* specified collection
|
||||
* @param c the collection which contains the elements to add
|
||||
* @throws ArrayIndexOutOfBoundsException if {@code index} does not
|
||||
* fall within the range of number of elements currently held
|
||||
* @throws NullPointerException if {@code c} is null
|
||||
*/
|
||||
public void addAll(int index, Collection<? extends E> c) {
|
||||
if (index < 0 || index > getSize()) {
|
||||
throw new ArrayIndexOutOfBoundsException("index out of range: " +
|
||||
index);
|
||||
}
|
||||
|
||||
if (c.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
delegate.addAll(index, c);
|
||||
fireIntervalAdded(this, index, index + c.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeObject(delegate);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
delegate=(Vector<E>) in.readObject();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
@@ -0,0 +1,133 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.kne.debug.TimeDebugger;
|
||||
public class ByteBufferAllocator {
|
||||
private List<ByteBufferPool> bbfps=new ArrayList<>();
|
||||
|
||||
private ByteBufferPool[]bbfpsarr;
|
||||
|
||||
|
||||
private ReferenceQueue<ByteBuffer> refq=new ReferenceQueue<>();
|
||||
private boolean isDirect;
|
||||
|
||||
public ByteBufferAllocator(boolean isDirect) {
|
||||
this.isDirect=isDirect;
|
||||
int i=1;
|
||||
int maxi=0;
|
||||
int mps=16;
|
||||
for (int j = 0; j < 18; j++) {
|
||||
int count=100;
|
||||
mps+=count;
|
||||
bbfps.add(new ByteBufferPool(mps, i,isDirect));
|
||||
maxi=i;
|
||||
i<<=1;
|
||||
}
|
||||
bbfpsarr=new ByteBufferPool[maxi];
|
||||
for (int j = 0; j < bbfpsarr.length; j++) {
|
||||
bbfpsarr[j]=getByteBufferPool(j);
|
||||
}
|
||||
|
||||
Thread t= new Thread(()->{
|
||||
while(true) {
|
||||
try {
|
||||
Reference<? extends ByteBuffer> ref;
|
||||
ref = refq.remove();
|
||||
if(ref!=null) {
|
||||
ref.clear();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.setPriority(Thread.MAX_PRIORITY-1);
|
||||
t.start();
|
||||
}
|
||||
public ByteBuffer allocate(int capacity) {
|
||||
if(true) {
|
||||
return allocateHeap(capacity);
|
||||
}
|
||||
//new Exception().printStackTrace();
|
||||
ByteBufferPool bbfp=bbfpsarr[capacity];
|
||||
ByteBuffer bbf=null;
|
||||
try {
|
||||
bbf=bbfp.borrow();
|
||||
}catch(OutOfMemoryError err) {
|
||||
System.gc();
|
||||
Thread.yield();
|
||||
bbf=bbfp.borrow();
|
||||
}
|
||||
ByteBuffer bbfs=bbf.slice(0, capacity);
|
||||
|
||||
new ByteBufferPhantomReference(bbfs,refq,bbf,bbfp);
|
||||
return bbfs;
|
||||
}
|
||||
private static ByteBuffer allocateHeap(int capacity) {
|
||||
return ByteBuffer.wrap(new byte[capacity]);
|
||||
}
|
||||
private ByteBufferPool getByteBufferPool(int capacity) {
|
||||
int elen=0;
|
||||
for (int i = 0; i < bbfps.size(); i++) {
|
||||
ByteBufferPool bfp=bbfps.get(i);
|
||||
if(capacity<=(elen= bfp.getLength())) {
|
||||
return bfp;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("capacity:"+capacity+">"+elen);
|
||||
}
|
||||
private static class ByteBufferPhantomReference extends PhantomReference<ByteBuffer>{
|
||||
|
||||
private static AtomicReference<ByteBufferPhantomReference> first=new AtomicReference<>(null);
|
||||
|
||||
private AtomicReference<ByteBufferPhantomReference> next=new AtomicReference<>(null);
|
||||
private AtomicReference<ByteBufferPhantomReference> prev=new AtomicReference<>(null);
|
||||
|
||||
private ByteBuffer father;
|
||||
private ByteBufferPool pool;
|
||||
|
||||
public ByteBufferPhantomReference(ByteBuffer referent, ReferenceQueue<? super ByteBuffer> q,ByteBuffer father,ByteBufferPool pool) {
|
||||
super(referent, q);
|
||||
this.father=father;
|
||||
this.pool=pool;
|
||||
insert();
|
||||
}
|
||||
|
||||
private void insert() {
|
||||
ByteBufferPhantomReference refn= first.getAndSet(this);
|
||||
if(refn!=null) {
|
||||
next.set(refn);
|
||||
refn.prev.set(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
ByteBufferPhantomReference prevn= prev.getAndSet(null);
|
||||
ByteBufferPhantomReference nextn=next.getAndSet(null);
|
||||
if(prevn!=null)
|
||||
prevn.next.set(nextn);
|
||||
if(nextn!=null)
|
||||
nextn.prev.set(prevn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
//System.out.println("clear");
|
||||
pool.back(father);
|
||||
remove();
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
|
||||
public class ByteBufferPool {
|
||||
private AtomicReferenceArray< ByteBuffer> rec;
|
||||
private volatile AtomicInteger pos=new AtomicInteger( 0);
|
||||
//private Lock lock=new SpinLock();
|
||||
|
||||
private int maxcount;
|
||||
private int length;
|
||||
private int mcj;
|
||||
private boolean direct;
|
||||
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
this.direct=direct;
|
||||
rec=new AtomicReferenceArray<ByteBuffer>(maxcount);
|
||||
mcj= rec.length()-1;
|
||||
}
|
||||
public ByteBufferPool(int maxcount, int length) {
|
||||
this(maxcount, length, true);
|
||||
}
|
||||
public void back(ByteBuffer b) {
|
||||
if(b.capacity()!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
b.clear();
|
||||
|
||||
|
||||
if(pos.get()<=mcj) {
|
||||
int d=pos.getAndIncrement();
|
||||
if(d>mcj)
|
||||
d=mcj;
|
||||
if(d<0)
|
||||
d=0;
|
||||
rec.compareAndSet(d,null,b);
|
||||
}
|
||||
|
||||
}
|
||||
public ByteBuffer borrow() {
|
||||
ByteBuffer b=null;
|
||||
|
||||
if(pos.get()>0) {
|
||||
int d=pos.decrementAndGet();
|
||||
if(d>mcj)
|
||||
d=mcj;
|
||||
if(d<0)
|
||||
d=0;
|
||||
b=rec.getAndSet(d,null);
|
||||
}
|
||||
|
||||
if(b==null) {
|
||||
if(direct)
|
||||
b=ByteBuffer.allocateDirect(length);
|
||||
else
|
||||
b=ByteBuffer.allocate(length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Flow.Subscriber;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.kne.cloud.network.klalb.ByteArrayPool;
|
||||
import org.kne.cloud.network.klalb.DATATPacket;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.net.NetworkInterface;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Duration;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -31,6 +32,15 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
||||
private List<MultipurposeSocketAddress> msas;
|
||||
|
||||
private volatile Consumer<MultipurposeSocketAddress> con;
|
||||
private long timeInterval;
|
||||
|
||||
public long getTimeInterval() {
|
||||
return timeInterval;
|
||||
}
|
||||
|
||||
public void setTimeInterval(long timeInterval) {
|
||||
this.timeInterval = timeInterval;
|
||||
}
|
||||
|
||||
public NetworkInterface getNinterface() {
|
||||
return ninterface;
|
||||
@@ -53,13 +63,14 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
||||
}
|
||||
|
||||
public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface,
|
||||
List<MultipurposeSocketAddress> msas) throws IOException {
|
||||
List<MultipurposeSocketAddress> msas,long timeInterval) throws IOException {
|
||||
soc = new MulticastSocket(bind);
|
||||
soc.joinGroup(group, ninterface);
|
||||
this.bind = bind;
|
||||
this.group = group;
|
||||
this.ninterface = ninterface;
|
||||
this.msas = msas;
|
||||
this.timeInterval=timeInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,7 +115,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
||||
|
||||
}
|
||||
|
||||
Thread.sleep(10000L);
|
||||
Thread.sleep(timeInterval);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -133,11 +144,13 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
||||
dis.close();
|
||||
MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(),
|
||||
port);
|
||||
try {
|
||||
InetAddress mpsai=mpsa.getInetAddress();
|
||||
//System.out.println(mpsa);
|
||||
Enumeration<InetAddress> ei = ninterface.getInetAddresses();
|
||||
while (ei.hasMoreElements()) {
|
||||
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||
if (inetAddress.equals(mpsa.getInetAddress())) {
|
||||
if (inetAddress.equals(mpsai)) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
@@ -145,13 +158,16 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
|
||||
if (con != null) {
|
||||
con.accept(mpsa);
|
||||
}
|
||||
|
||||
}catch(UnknownHostException e) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println(bind + " " + group + " " + ninterface);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
|
||||
close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -7,85 +7,50 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.cloud.network.klalb.ByteArrayPool;
|
||||
import org.kne.cloud.network.klalb.ByteBufferPool;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
public abstract class NetworkPacket implements Comparable<NetworkPacket>{
|
||||
private static final boolean debugPassport=false;
|
||||
|
||||
public static final ByteBufferAllocator bufferAllocator=new ByteBufferAllocator(true);
|
||||
|
||||
|
||||
public static final ByteArrayPool dataarraypool_65535=new ByteArrayPool(10000, 65535);
|
||||
//public static final ByteArrayPool dataarraypool_65535=new ByteArrayPool(10000, 65535);
|
||||
|
||||
public static final ByteBufferPool databufferpool_65535=new ByteBufferPool(10000, 65535,false);
|
||||
//public static final ByteBufferPool databufferpool_65535=new ByteBufferPool(10000, 65535,false);
|
||||
|
||||
public static final ByteBufferPool databufferpool_2048=new ByteBufferPool(10000, 2048,false);
|
||||
//public static final ByteBufferPool databufferpool_2048=new ByteBufferPool(10000, 2048,false);
|
||||
|
||||
public static final ByteBufferPool databufferpool_40=new ByteBufferPool(10000, 40,false);
|
||||
//public static final ByteBufferPool databufferpool_40=new ByteBufferPool(10000, 40,false);
|
||||
|
||||
|
||||
|
||||
private TimeDebugger passport;
|
||||
private final TimeDebugger passport;
|
||||
{
|
||||
if(debugPassport) {
|
||||
passport=new TimeDebugger();
|
||||
passport.putTime(getClass().getSimpleName()+ "_create");
|
||||
}else {
|
||||
passport=null;
|
||||
}
|
||||
}
|
||||
|
||||
public void putTimePassport(String label) {
|
||||
public final void putTimePassport(String label) {
|
||||
if(passport!=null) {
|
||||
passport.putTime(label);
|
||||
}
|
||||
}
|
||||
|
||||
public void printPassport() {
|
||||
public final void printPassport() {
|
||||
if(passport!=null) {
|
||||
passport.printWithTimeFilter(100000000L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private volatile boolean disposeAfterSend=false;
|
||||
|
||||
public boolean isDisposeAfterSend() {
|
||||
return disposeAfterSend;
|
||||
}
|
||||
public void setDisposeAfterSend(boolean disposeAfterSend) {
|
||||
this.disposeAfterSend = disposeAfterSend;
|
||||
}
|
||||
private volatile boolean disposed=false;
|
||||
private Lock disposeLock=new ReentrantLock();
|
||||
public boolean isDisposed() {
|
||||
return disposed;
|
||||
}
|
||||
public Lock getDisposeLock() {
|
||||
return disposeLock;
|
||||
}
|
||||
|
||||
public abstract long getLength();
|
||||
public void dispose() {
|
||||
/*disposeLock.lock();
|
||||
try {*/
|
||||
disposed=true;
|
||||
/*}finally {
|
||||
disposeLock.unlock();
|
||||
}*/
|
||||
}
|
||||
|
||||
public void lockAll() {
|
||||
disposeLock.lock();
|
||||
}
|
||||
|
||||
public boolean isSomeDisposed() {
|
||||
return disposed;
|
||||
}
|
||||
|
||||
public void unlockAll() {
|
||||
disposeLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
public long getPriority() {
|
||||
return priority;
|
||||
@@ -118,22 +83,14 @@ public abstract class NetworkPacket implements Comparable<NetworkPacket>{
|
||||
}
|
||||
}
|
||||
|
||||
public void disposeAll() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void doDisposeAfterSend() {
|
||||
if(isDisposeAfterSend())
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void genseq() {
|
||||
this.sendseq=seqgen.getAndIncrement();
|
||||
}
|
||||
|
||||
protected abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
|
||||
protected abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException{
|
||||
public abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
|
||||
public abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException{
|
||||
readFromChannel(din,-1);
|
||||
}
|
||||
protected abstract boolean needEndPosition();
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.kne.cloud.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -11,14 +12,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.kne.cloud.network.klalb.ByteBufferPool;
|
||||
|
||||
public class PacketRebuilder {
|
||||
public class PacketRebuilder implements ReadableByteChannel{
|
||||
private static final ByteBufferPool bbfp=new ByteBufferPool(100, 65535);
|
||||
private long timeout;
|
||||
|
||||
public PacketRebuilder(long timeout) {
|
||||
public PacketRebuilder(ReadableByteChannel readableChannel,long timeout) {
|
||||
this.timeout=timeout;
|
||||
this.readableChannel=readableChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,10 +58,18 @@ public class PacketRebuilder {
|
||||
|
||||
|
||||
}
|
||||
public void read(ByteBuffer des,ReadableByteChannel rc) throws IOException {
|
||||
while(true) {
|
||||
|
||||
private ReadableByteChannel readableChannel;
|
||||
|
||||
|
||||
public ReadableByteChannel getReadableChannel() {
|
||||
return readableChannel;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer des) throws IOException {
|
||||
while(readableChannel.isOpen()) {
|
||||
ByteBuffer cac=bbfp.borrow();
|
||||
rc.read(cac);
|
||||
readableChannel.read(cac);
|
||||
cac.flip();
|
||||
int ser=cac.getInt(0);
|
||||
int countofpiece=cac.get(4);
|
||||
@@ -75,12 +83,12 @@ public class PacketRebuilder {
|
||||
ReceiveEntry reet=recvc.get(ser);
|
||||
reet.getByteBuffers()[i]=cac;
|
||||
if(reet.isFull()) {
|
||||
rebuild(des ,reet.getByteBuffers());
|
||||
int rez= rebuild(des ,reet.getByteBuffers());
|
||||
for (int j = 0; j < reet.getByteBuffers().length; j++) {
|
||||
bbfp.back(reet.getByteBuffers()[j]);
|
||||
}
|
||||
recvc.remove(ser);
|
||||
return ;
|
||||
return rez;
|
||||
}
|
||||
for (Iterator<Entry<Integer, ReceiveEntry>> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Integer, ReceiveEntry> type = (Entry<Integer, ReceiveEntry>) iterator.next();
|
||||
@@ -94,17 +102,30 @@ public class PacketRebuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public void rebuild(ByteBuffer des, ByteBuffer[]src) {
|
||||
//System.out.print("Rebuild:");
|
||||
public int rebuild(ByteBuffer des, ByteBuffer[]src) {
|
||||
//StringBuilder sbd=new StringBuilder("Rebuild:");
|
||||
int oldpos=des.position();
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
src[i].getInt();
|
||||
src[i].get();
|
||||
src[i].get();
|
||||
des.put(src[i]);
|
||||
//System.out.print(src[i].limit()+" ");
|
||||
// sbd.append(src[i].limit()+" ");
|
||||
}
|
||||
//System.out.println();
|
||||
//System.out.println(sbd);
|
||||
return des.position()-oldpos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return readableChannel.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
readableChannel.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@ import java.nio.channels.WritableByteChannel;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.klalb.ByteBufferPool;
|
||||
|
||||
public class PacketSpliter {
|
||||
private int splitSize;
|
||||
private static final ByteBufferPool bbfp=new ByteBufferPool(100,65535,false);
|
||||
private volatile int splitSize;
|
||||
private AtomicInteger series=new AtomicInteger();
|
||||
|
||||
public PacketSpliter(int splitSize) {
|
||||
private WritableByteChannel writableChannel;
|
||||
public PacketSpliter(WritableByteChannel writableChannel,int splitSize) {
|
||||
this.writableChannel=writableChannel;
|
||||
this.splitSize=splitSize;
|
||||
}
|
||||
|
||||
@@ -21,28 +19,37 @@ public class PacketSpliter {
|
||||
return splitSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public WritableByteChannel getWritableChannel() {
|
||||
return writableChannel;
|
||||
}
|
||||
|
||||
public void setSplitSize(int splitSize) {
|
||||
this.splitSize = splitSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PacketSpliter [splitSize=" + splitSize + "]";
|
||||
}
|
||||
|
||||
public void write(ByteBuffer bb,WritableByteChannel wc) throws IOException{
|
||||
public void write(ByteBuffer bb) throws IOException{
|
||||
ByteBuffer[]bbssp= split(bb);
|
||||
for (int i = 0; i < bbssp.length; i++) {
|
||||
wc.write(bbssp[i]);
|
||||
bbfp.back(bbssp[i]);
|
||||
writableChannel.write(bbssp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer[] split(ByteBuffer bb) {
|
||||
//System.out.print("Split:");
|
||||
//StringBuilder sbd=new StringBuilder("Split:");
|
||||
int splitSizex=splitSize;
|
||||
int lenth=bb.limit();
|
||||
int countofpiece=(lenth-1)/splitSize+1;
|
||||
int remain=lenth%splitSize;
|
||||
int countofpiece=(lenth-1)/splitSizex+1;
|
||||
int remain=lenth%splitSizex;
|
||||
ByteBuffer[]pieces=new ByteBuffer[countofpiece];
|
||||
for (int i = 0; i < pieces.length; i++) {
|
||||
pieces[i]=bbfp.borrow();
|
||||
pieces[i]=NetworkPacket.bufferAllocator.allocate(splitSizex+6);
|
||||
}
|
||||
int sern=series.getAndIncrement();
|
||||
for (int i = 0; i < pieces.length; i++) {
|
||||
@@ -53,10 +60,10 @@ public class PacketSpliter {
|
||||
bb.limit(Math.min(bb.remaining(), pieces[i].remaining())+bb.position());
|
||||
pieces[i].put(bb);
|
||||
bb.limit(bbl);
|
||||
//System.out.print(pieces[i].position()+" ");
|
||||
//sbd.append(pieces[i].position()+" ");
|
||||
pieces[i].flip();
|
||||
}
|
||||
//System.out.println();
|
||||
//System.out.println(sbd);
|
||||
return pieces;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ProtocolFamily;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketOptions;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocketImpl;
|
||||
|
||||
|
||||
public class RawSocket {
|
||||
|
||||
|
||||
public static final ProtocolFamily PF_INET=StandardProtocolFamily.INET;
|
||||
|
||||
|
||||
public static final ProtocolFamily PF_INET6=StandardProtocolFamily.INET6;
|
||||
|
||||
private static final VarHandle STATE ;
|
||||
static {
|
||||
try {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
STATE = l.findVarHandle(RawSocket.class, "state", int.class);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
//the underlying SocketImpl, may be null, may be swapped when connecting
|
||||
private RawSocketImpl impl;
|
||||
|
||||
// state bits
|
||||
private static final int SOCKET_CREATED = 1 << 0; // impl.create(boolean) called
|
||||
private static final int BOUND = 1 << 1;
|
||||
private static final int CONNECTED = 1 << 2;
|
||||
private static final int CLOSED = 1 << 3;
|
||||
private static final int SHUT_IN = 1 << 9;
|
||||
private static final int SHUT_OUT = 1 << 10;
|
||||
private volatile int state;
|
||||
|
||||
// used to coordinate creating and closing underlying socket
|
||||
private final Object socketLock = new Object();
|
||||
|
||||
|
||||
InetAddress connectedAddress = null;
|
||||
|
||||
private boolean explicitFilter = false;
|
||||
private int bytesLeftToFilter;
|
||||
/**
|
||||
* Atomically sets state to the result of a bitwise OR of the current value
|
||||
* and the given mask.
|
||||
* @return the previous state value
|
||||
*/
|
||||
private int getAndBitwiseOrState(int mask) {
|
||||
return (int) STATE.getAndBitwiseOr(this, mask);
|
||||
}
|
||||
|
||||
private static boolean isBound(int s) {
|
||||
return (s & BOUND) != 0;
|
||||
}
|
||||
|
||||
private static boolean isConnected(int s) {
|
||||
return (s & CONNECTED) != 0;
|
||||
}
|
||||
|
||||
private static boolean isClosed(int s) {
|
||||
return (s & CLOSED) != 0;
|
||||
}
|
||||
|
||||
private static boolean isInputShutdown(int s) {
|
||||
return (s & SHUT_IN) != 0;
|
||||
}
|
||||
|
||||
private static boolean isOutputShutdown(int s) {
|
||||
return (s & SHUT_OUT) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected RawSocket(RawSocketImpl impl) {
|
||||
this.impl=impl;
|
||||
}
|
||||
|
||||
public RawSocket(RawSocketImpl impl, Inet6Address bindAddress) throws SocketException {
|
||||
this.impl=impl;
|
||||
bind(bindAddress);
|
||||
}
|
||||
|
||||
public RawSocket(KLALBVirtualRawSocketImpl impl, Inet6Address bindAddress, int bindProtocol) throws SocketException {
|
||||
this.impl=impl;
|
||||
bind(bindAddress,bindProtocol);
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return isConnected(state);
|
||||
}
|
||||
public boolean isBound() {
|
||||
return isBound(state);
|
||||
}
|
||||
public boolean isOpen() {
|
||||
return !isClosed(state);
|
||||
}
|
||||
public boolean isClosed() {
|
||||
return isClosed(state);
|
||||
}
|
||||
private void checkAddress(InetAddress addr, String op) {
|
||||
if (addr == null) {
|
||||
return;
|
||||
}
|
||||
if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
|
||||
throw new IllegalArgumentException(op + ": invalid address type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private RawSocketImpl getImpl() throws SocketException {
|
||||
if ((state & SOCKET_CREATED) == 0) {
|
||||
synchronized (socketLock) {
|
||||
int s = state; // re-read state
|
||||
if ((s & SOCKET_CREATED) == 0) {
|
||||
if (isClosed(s)) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
RawSocketImpl impl = this.impl;
|
||||
if (impl == null) {
|
||||
this.impl = impl = createImpl();
|
||||
}
|
||||
try {
|
||||
impl.create();
|
||||
} catch (SocketException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new SocketException(e.getMessage(), e);
|
||||
}
|
||||
getAndBitwiseOrState(SOCKET_CREATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
return impl;
|
||||
}
|
||||
|
||||
private static RawSocketImpl createImpl() {
|
||||
RawSocketImplFactory factory = RawSocket.factory;
|
||||
if (factory != null) {
|
||||
return factory.createRawSocketImpl();
|
||||
} else {
|
||||
return null;
|
||||
// RawSocketImpl delegate = RawSocketImpl.createPlatformSocketImpl(false);
|
||||
// return new SocksSocketImpl(delegate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static volatile RawSocketImplFactory factory;
|
||||
|
||||
static RawSocketImplFactory socketImplFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated(since = "17")
|
||||
public static synchronized void setSocketImplFactory(RawSocketImplFactory fac)
|
||||
throws IOException
|
||||
{
|
||||
if (factory != null) {
|
||||
throw new SocketException("factory already defined");
|
||||
}
|
||||
@SuppressWarnings("removal")
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkSetFactory();
|
||||
}
|
||||
factory = fac;
|
||||
}
|
||||
public void bind(InetAddress address) throws SocketException {
|
||||
bind(address,-1);
|
||||
}
|
||||
public void bind(InetAddress address,int protocolNumber)
|
||||
throws SocketException
|
||||
{
|
||||
int s = state;
|
||||
if (isClosed(s))
|
||||
throw new SocketException("Socket is closed");
|
||||
if (isBound(s))
|
||||
throw new SocketException("Already bound");
|
||||
|
||||
|
||||
|
||||
if (address == null) {
|
||||
try {
|
||||
address = Inet6Address.getByName("::0");
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
checkAddress (address, "bind");
|
||||
getImpl().bind(address,protocolNumber);
|
||||
getAndBitwiseOrState(BOUND);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void bindDevice(String device)
|
||||
throws UnsupportedOperationException, IllegalStateException, IOException
|
||||
{
|
||||
if(!isOpen())
|
||||
throw new IllegalStateException();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public InetAddress getLocalAddress() {
|
||||
if (isClosed())
|
||||
return null;
|
||||
InetAddress in;
|
||||
try {
|
||||
in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
|
||||
if (in.isAnyLocalAddress()) {
|
||||
in = InetAddress.getByName("::0");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
in = InetAddress.getByName("::0");
|
||||
} catch (UnknownHostException e1) {
|
||||
e1.printStackTrace();
|
||||
in=null;
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
synchronized (socketLock) {
|
||||
if ((state & CLOSED) == 0) {
|
||||
int s = getAndBitwiseOrState(CLOSED);
|
||||
if ((s & (SOCKET_CREATED | CLOSED)) == SOCKET_CREATED) {
|
||||
// close underlying socket if created
|
||||
impl.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setIPHeaderInclude(boolean on) throws IOException {
|
||||
impl.setIPHeaderInclude(on);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean getIPHeaderInclude() throws IOException {
|
||||
return impl.getIPHeaderInclude();
|
||||
}
|
||||
|
||||
public void setSendBufferSize(int size) throws SocketException {
|
||||
if (size <= 0)
|
||||
throw new IllegalArgumentException("negative send size");
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setOption(SocketOptions.SO_SNDBUF, size);
|
||||
}
|
||||
|
||||
public int getSendBufferSize() throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
int result = 0;
|
||||
Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
|
||||
if (o instanceof Integer i) {
|
||||
result = i.intValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setReceiveBufferSize(int size) throws SocketException {
|
||||
if (size <= 0)
|
||||
throw new IllegalArgumentException("invalid receive size");
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setOption(SocketOptions.SO_RCVBUF, size);
|
||||
}
|
||||
|
||||
public int getReceiveBufferSize() throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
int result = 0;
|
||||
Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
|
||||
if (o instanceof Integer i) {
|
||||
result = i.intValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setUseSelectTimeout(boolean useSelect) throws IOException {
|
||||
impl.setUseSelectTimeout(useSelect);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean getUseSelectTimeout() throws IOException {
|
||||
return impl.getUseSelectTimeout();
|
||||
}
|
||||
|
||||
|
||||
/* public void setSendTimeout(int timeout) throws SocketException {
|
||||
impl.setSendTimeout( timeout);
|
||||
}
|
||||
|
||||
|
||||
public int getSendTimeout() throws SocketException {
|
||||
return impl.getSendTimeout();
|
||||
}*/
|
||||
|
||||
|
||||
public void setSoTimeout(int timeout) throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
if (timeout < 0)
|
||||
throw new IllegalArgumentException("timeout can't be negative");
|
||||
getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
|
||||
}
|
||||
|
||||
|
||||
public int getSoTimeout() throws SocketException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
|
||||
/* extra type safety */
|
||||
if (o instanceof Integer i) {
|
||||
return i.intValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void send(DatagramPacket p) throws IOException {
|
||||
synchronized (p) {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
InetAddress packetAddress = p.getAddress();
|
||||
checkAddress(packetAddress, "send");
|
||||
if (isConnected()) {
|
||||
// we're connected
|
||||
if (packetAddress == null) {
|
||||
p.setAddress(connectedAddress);
|
||||
} else if ((!packetAddress.equals(connectedAddress)) ) {
|
||||
throw new IllegalArgumentException("connected address " +
|
||||
"and packet address" +
|
||||
" differ");
|
||||
}
|
||||
|
||||
} else {
|
||||
if (packetAddress == null) {
|
||||
throw new IllegalArgumentException("Address not set");
|
||||
}
|
||||
}
|
||||
// Check whether the socket is bound
|
||||
if (!isBound())
|
||||
bind(InetAddress.getByName("::0"));
|
||||
// call the method to send
|
||||
getImpl().send(p);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void receive(DatagramPacket p) throws IOException {
|
||||
synchronized (p) {
|
||||
if (!isBound())
|
||||
bind(InetAddress.getByName("::0"));
|
||||
DatagramPacket tmp = null;
|
||||
if (explicitFilter) {
|
||||
// We have to do the filtering the old fashioned way since
|
||||
// the native impl doesn't support connect or the connect
|
||||
// via the impl failed, or .. "explicitFilter" may be set when
|
||||
// a socket is connected via the impl, for a period of time
|
||||
// when packets from other sources might be queued on socket.
|
||||
boolean stop = false;
|
||||
while (!stop) {
|
||||
// peek at the packet to see who it is from.
|
||||
DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
|
||||
getImpl().peekData(peekPacket);
|
||||
InetAddress peekAddress = peekPacket.getAddress();
|
||||
if ((!connectedAddress.equals(peekAddress)) ) {
|
||||
// throw the packet away and silently continue
|
||||
tmp = new DatagramPacket(
|
||||
new byte[1024], 1024);
|
||||
getImpl().receive(tmp);
|
||||
if (explicitFilter) {
|
||||
if (checkFiltering(tmp)) {
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the security check succeeds, or the datagram is
|
||||
// connected then receive the packet
|
||||
getImpl().receive(p);
|
||||
if (explicitFilter && tmp == null) {
|
||||
// packet was not filtered, account for it here
|
||||
checkFiltering(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
private boolean checkFiltering(DatagramPacket p) throws SocketException {
|
||||
bytesLeftToFilter -= p.getLength();
|
||||
if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
|
||||
explicitFilter = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketOption;
|
||||
import java.net.SocketOptions;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class RawSocketImpl implements SocketOptions{
|
||||
int dataAvailable() {
|
||||
// default impl returns zero, which disables the calling
|
||||
// functionality
|
||||
return 0;
|
||||
}
|
||||
protected abstract void create()throws IOException;
|
||||
|
||||
protected abstract void setIPHeaderInclude(boolean on)throws IOException;
|
||||
|
||||
protected abstract boolean getIPHeaderInclude()throws IOException;
|
||||
|
||||
protected abstract void setUseSelectTimeout(boolean useSelect)throws IOException;
|
||||
|
||||
protected abstract boolean getUseSelectTimeout()throws IOException;
|
||||
|
||||
protected abstract void setSendTimeout(int timeout)throws IOException;
|
||||
|
||||
protected abstract int getSendTimeout()throws IOException;
|
||||
|
||||
protected abstract void setReceiveTimeout(int timeout)throws IOException;
|
||||
|
||||
protected abstract int getReceiveTimeout()throws IOException;
|
||||
|
||||
protected abstract void close();
|
||||
|
||||
protected abstract void bind(InetAddress address,int protocolNumber)throws SocketException;
|
||||
|
||||
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
|
||||
Objects.requireNonNull(name);
|
||||
throw new UnsupportedOperationException("'" + name + "' not supported");
|
||||
}
|
||||
|
||||
protected <T> T getOption(SocketOption<T> name) throws IOException {
|
||||
Objects.requireNonNull(name);
|
||||
throw new UnsupportedOperationException("'" + name + "' not supported");
|
||||
}
|
||||
|
||||
protected abstract void join(InetAddress inetaddr) throws IOException;
|
||||
|
||||
|
||||
protected abstract void leave(InetAddress inetaddr) throws IOException;
|
||||
|
||||
|
||||
protected abstract void joinGroup(InetAddress mcastaddr,
|
||||
NetworkInterface netIf)
|
||||
throws IOException;
|
||||
|
||||
|
||||
protected abstract void leaveGroup(InetAddress mcastaddr,
|
||||
NetworkInterface netIf)
|
||||
throws IOException;
|
||||
protected abstract void send(DatagramPacket p) throws IOException;
|
||||
protected abstract InetAddress peek() throws IOException;
|
||||
|
||||
|
||||
protected abstract void peekData(DatagramPacket p) throws IOException;
|
||||
|
||||
protected abstract void receive(DatagramPacket p) throws IOException;
|
||||
|
||||
protected void connect(InetAddress address) throws SocketException {
|
||||
throw new SocketException("connect not implemented");
|
||||
}
|
||||
|
||||
protected void disconnect() {
|
||||
throw new UncheckedIOException(new SocketException("disconnect not implemented"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
public interface RawSocketImplFactory {
|
||||
RawSocketImpl createRawSocketImpl();
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{
|
||||
while(flag){
|
||||
try {
|
||||
SocketChannel soce=serverSocketChannel.accept();
|
||||
ThreadTool.makePThreadIfSupport("端口监听线程",()->{
|
||||
ThreadTool.makePThreadIfSupport("端口请求处理线程",()->{
|
||||
if(con!=null) {
|
||||
try {
|
||||
con.accept(soce);
|
||||
@@ -71,7 +71,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{
|
||||
if(serverSocketChannel==null) {
|
||||
throw new IOException(multipurposeSocketAddress.getType()+" unsupport SocketChannel");
|
||||
}
|
||||
new Thread(r).start();
|
||||
ThreadTool.makeVThread("端口监听线程", r).start();
|
||||
}
|
||||
public void close() {
|
||||
flag=false;
|
||||
|
||||
@@ -63,6 +63,7 @@ public class SpeedLimiter {
|
||||
waitingtime.addAndGet(datasize*1000000000L/limitspeedx);
|
||||
}
|
||||
}
|
||||
//用系统计时器的时刻相减得到经过的时间,与数据包除以限速值得到的应消耗的时间做对比,若时间还未到达发送下一个数据包的时机,则返回false
|
||||
public boolean checkTransmit(long datasize) {
|
||||
long limitspeedx=limitspeed;
|
||||
if(limitspeedx<=0) {
|
||||
|
||||
@@ -3,8 +3,8 @@ package org.kne.cloud.network;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ThreadTool {
|
||||
public static boolean first=true;
|
||||
public static boolean forceD=true;
|
||||
public static boolean first=true;
|
||||
public static Thread makeVThreadIfSupport(String name,Runnable r) {
|
||||
if(forceD)
|
||||
return new Thread(r, name);
|
||||
@@ -64,4 +64,47 @@ public class ThreadTool {
|
||||
rt.setDaemon(true);
|
||||
return rt;
|
||||
}
|
||||
public static Thread makeVDaemonThread(String name, Runnable r) {
|
||||
try { //return new Thread(r, name);
|
||||
Class<?> c=Class.forName("java.lang.Thread");
|
||||
Method m= c.getDeclaredMethod("ofVirtual", null);
|
||||
Object o=m.invoke(null, null);
|
||||
Class<?> cb=Class.forName("java.lang.Thread$Builder");
|
||||
Method mn= cb.getDeclaredMethod("name", String.class);
|
||||
mn.invoke(o, name);
|
||||
Method mu= cb.getDeclaredMethod("unstarted", Runnable.class);
|
||||
return (Thread) mu.invoke(o, r);
|
||||
//return Thread.ofVirtual().name(name).unstarted(r);
|
||||
}catch(Throwable e) {
|
||||
//e.printStackTrace();
|
||||
if(first) {
|
||||
System.out.println("提示:请使用java21以上版本以提高本软件的数据转发性能!");
|
||||
first=false;
|
||||
}
|
||||
Thread rt=new Thread(r, name);
|
||||
rt.setDaemon(true);
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
public static Thread makeVThread(String name, Runnable r) {
|
||||
|
||||
try { //return new Thread(r, name);
|
||||
Class<?> c=Class.forName("java.lang.Thread");
|
||||
Method m= c.getDeclaredMethod("ofVirtual", null);
|
||||
Object o=m.invoke(null, null);
|
||||
Class<?> cb=Class.forName("java.lang.Thread$Builder");
|
||||
Method mn= cb.getDeclaredMethod("name", String.class);
|
||||
mn.invoke(o, name);
|
||||
Method mu= cb.getDeclaredMethod("unstarted", Runnable.class);
|
||||
return (Thread) mu.invoke(o, r);
|
||||
//return Thread.ofVirtual().name(name).unstarted(r);
|
||||
}catch(Throwable e) {
|
||||
//e.printStackTrace();
|
||||
if(first) {
|
||||
System.out.println("提示:请使用java21以上版本以提高本软件的数据转发性能!");
|
||||
first=false;
|
||||
}
|
||||
return new Thread(r, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocketImpl;
|
||||
|
||||
public class VirtualRawSocket extends RawSocket {
|
||||
|
||||
private VirtualRawSocketImpl virtualImpl;
|
||||
protected VirtualRawSocket(VirtualRawSocketImpl virtualImpl) {
|
||||
super(virtualImpl);
|
||||
this.virtualImpl =virtualImpl;
|
||||
}
|
||||
public VirtualRawSocket(KLALBVirtualRawSocketImpl virtualImpl, Inet6Address bindAddress) throws SocketException {
|
||||
super(virtualImpl,bindAddress);
|
||||
this.virtualImpl =virtualImpl;
|
||||
}
|
||||
public VirtualRawSocket(KLALBVirtualRawSocketImpl virtualImpl, Inet6Address bindAddress,
|
||||
int bindProtocol) throws SocketException {
|
||||
super(virtualImpl,bindAddress,bindProtocol);
|
||||
this.virtualImpl =virtualImpl;
|
||||
}
|
||||
protected VirtualRawSocketImpl getVirtualImpl() {
|
||||
return virtualImpl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
|
||||
public abstract class VirtualRawSocketImpl extends RawSocketImpl {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -14,10 +14,16 @@ public interface IPv6NetworkLink {
|
||||
public boolean isLoopBack();
|
||||
public Inet6AddressGroup getAddressGroup();
|
||||
public List<Neighbor> getNeighborsInfo();
|
||||
public List<RouteItem> getRouteItems();
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException;
|
||||
public boolean isCongress(IPv6Packet iPv6Packet);
|
||||
public boolean isCongress(IPv6Packet iPv6Packet,double scale);
|
||||
public default boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
return isCongress(iPv6Packet, 1.0);
|
||||
}
|
||||
public String getName();
|
||||
public boolean isUp();
|
||||
public boolean canSend(IPv6Packet iPv6Packet);
|
||||
public void setReceiveConsumer(Consumer<IPv6Packet>con);
|
||||
void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer);
|
||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -11,9 +12,12 @@ import java.nio.channels.WritableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
|
||||
@@ -24,6 +28,29 @@ import org.kne.cloud.network.srv6.SRv6TLV;
|
||||
import org.pcap4j.packet.namednumber.IpNumber;
|
||||
|
||||
public class IPv6Packet extends NetworkPacket {
|
||||
|
||||
private long flowSeqMark=-1;
|
||||
|
||||
|
||||
|
||||
public long getFlowSeqMark() {
|
||||
return flowSeqMark;
|
||||
}
|
||||
|
||||
public void setFlowSeqMark(long flowSeqMark) {
|
||||
this.flowSeqMark = flowSeqMark;
|
||||
}
|
||||
|
||||
|
||||
private boolean TTLdecreased=false;
|
||||
|
||||
public boolean isTTLdecreased() {
|
||||
return TTLdecreased;
|
||||
}
|
||||
|
||||
public void setTTLdecreased(boolean tTLdecreased) {
|
||||
TTLdecreased = tTLdecreased;
|
||||
}
|
||||
private volatile ByteBuffer IPv6header ;
|
||||
|
||||
private volatile List<IPv6ExtHeader> headers = new ArrayList<>();
|
||||
@@ -41,7 +68,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
}
|
||||
|
||||
public IPv6Packet() {
|
||||
IPv6header = NetworkPacket.databufferpool_40.borrow();
|
||||
IPv6header = NetworkPacket.bufferAllocator.allocate(40);
|
||||
IPv6header.limit(IPv6_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
@@ -76,6 +103,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
|
||||
public void markCE() {
|
||||
IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000));
|
||||
//new Exception().printStackTrace();
|
||||
}
|
||||
|
||||
public boolean isCE() {
|
||||
@@ -114,7 +142,24 @@ public class IPv6Packet extends NetworkPacket {
|
||||
public void setHopLimit(int hopLimit) {
|
||||
IPv6header.put(7, (byte) hopLimit);
|
||||
}
|
||||
|
||||
public void getRawSourceAddress(byte[] sourceAddress) {
|
||||
IPv6header.get(8, sourceAddress, 0, sourceAddress.length);
|
||||
}
|
||||
|
||||
public void setRawSourceAddress(byte[] sourceAddress) {
|
||||
IPv6header.put(8, sourceAddress, 0, sourceAddress.length);
|
||||
}
|
||||
|
||||
public void getRawDestinationAddress(byte[] destinationAddress) {
|
||||
IPv6header.get(24, destinationAddress, 0,destinationAddress.length);
|
||||
|
||||
}
|
||||
|
||||
public void setRawDestinationAddress(byte[] destinationAddress) {
|
||||
IPv6header.put(24, destinationAddress, 0, destinationAddress.length);
|
||||
}
|
||||
|
||||
public Inet6Address getSourceAddress() {
|
||||
byte[] b = new byte[16];
|
||||
IPv6header.get(8, b, 0, b.length);
|
||||
@@ -163,29 +208,6 @@ public class IPv6Packet extends NetworkPacket {
|
||||
return calcPayloadLength()+IPv6_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDisposeAfterSend() {
|
||||
super.doDisposeAfterSend();
|
||||
payload.doDisposeAfterSend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer headerx = IPv6header;
|
||||
IPv6header = null;
|
||||
if(headerx!=null)
|
||||
NetworkPacket.databufferpool_40.back(headerx);*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeAll() {
|
||||
super.disposeAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).disposeAll();
|
||||
}
|
||||
payload.disposeAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@@ -241,7 +263,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
headers.add(ext);
|
||||
break;
|
||||
case 43:
|
||||
ByteBuffer bbf=NetworkPacket.databufferpool_2048.borrow();
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(2048);
|
||||
bbf.limit(4);
|
||||
while (bbf.hasRemaining()) {
|
||||
if (din.read(bbf) == -1) {
|
||||
@@ -296,7 +318,11 @@ public class IPv6Packet extends NetworkPacket {
|
||||
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din);
|
||||
this.payload=kp;
|
||||
break loop;
|
||||
|
||||
case 253:
|
||||
IPv6Payload epld=new IPv6EmptyPayload();
|
||||
epld.readFromChannel(din, payloadlength);
|
||||
this.payload=epld;
|
||||
break loop;
|
||||
default:
|
||||
IPv6Payload pld=new IPv6Payload(nextheader);
|
||||
pld.readFromChannel(din, payloadlength);
|
||||
@@ -376,35 +402,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
//System.out.println(payload);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void lockAll() {
|
||||
super.lockAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).lockAll();
|
||||
}
|
||||
payload.lockAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSomeDisposed() {
|
||||
if(super.isSomeDisposed()||payload.isSomeDisposed())
|
||||
return true;
|
||||
for (Iterator<IPv6ExtHeader> iterator = headers.iterator(); iterator.hasNext();) {
|
||||
IPv6ExtHeader iPv6ExtHeader = (IPv6ExtHeader) iterator.next();
|
||||
if(iPv6ExtHeader.isSomeDisposed())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockAll() {
|
||||
payload.unlockAll();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
headers.get(i).unlockAll();
|
||||
}
|
||||
super.unlockAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -434,7 +432,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
this.protocolNumber = protocolNumber;
|
||||
this.onDefault=isonDefault;
|
||||
if(onDefault)
|
||||
this.data=NetworkPacket.databufferpool_65535.borrow();
|
||||
this.data=NetworkPacket.bufferAllocator.allocate(65535);
|
||||
}
|
||||
|
||||
public int getProtocolNumber() {
|
||||
@@ -446,13 +444,13 @@ public class IPv6Packet extends NetworkPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(onDefault)
|
||||
dto.write(data.slice(0,data.limit()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
if(onDefault) {
|
||||
data.limit((int) length);
|
||||
while (data.hasRemaining()) {
|
||||
@@ -463,15 +461,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*if(onDefault) {
|
||||
ByteBuffer datax = data;
|
||||
data = null;
|
||||
NetworkPacket.databufferpool_65535.back(datax);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean needEndPosition() {
|
||||
@@ -480,6 +470,28 @@ public class IPv6Packet extends NetworkPacket {
|
||||
|
||||
}
|
||||
|
||||
public static class IPv6EmptyPayload extends IPv6Payload{
|
||||
|
||||
public IPv6EmptyPayload() {
|
||||
super(253, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class IPv6ExtHeader extends NetworkPacket{
|
||||
private ByteBuffer data ;
|
||||
|
||||
@@ -505,9 +517,9 @@ public class IPv6Packet extends NetworkPacket {
|
||||
this.protocolNumber = protocolNumber;
|
||||
this.onDefault=isonDefault;
|
||||
if(onDefault) {
|
||||
this.data=NetworkPacket.databufferpool_2048.borrow();
|
||||
this.data=NetworkPacket.bufferAllocator.allocate(2048);
|
||||
}else {
|
||||
this.data=NetworkPacket.databufferpool_40.borrow();
|
||||
this.data=NetworkPacket.bufferAllocator.allocate(8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +554,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(onDefault) {
|
||||
int ext=(data.limit()-8)/8;
|
||||
setExtLength(ext);
|
||||
@@ -553,7 +565,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
data.limit(8);
|
||||
while (data.hasRemaining()) {
|
||||
if (din.read(data) == -1) {
|
||||
@@ -576,19 +588,7 @@ public class IPv6Packet extends NetworkPacket {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer bbft=data;
|
||||
data=null;
|
||||
if(bbft!=null) {
|
||||
if(bbft.capacity()==40) {
|
||||
NetworkPacket.databufferpool_40.back(bbft);
|
||||
}else {
|
||||
NetworkPacket.databufferpool_2048.back(bbft);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -678,27 +678,37 @@ public class IPv6Packet extends NetworkPacket {
|
||||
public List<Inet6Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public List<IPv6SegmentRoutingTLV> getTlvs() {
|
||||
return tlvs;
|
||||
}
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
setExtLength(calcExtLength()/8);
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
int exl=calcExtLength();
|
||||
if(exl%8!=0) {
|
||||
throw new StreamCorruptedException("extLength % 8 !=0");
|
||||
}
|
||||
|
||||
setExtLength(exl/8);
|
||||
setLastEntry(addresses.size()-1);
|
||||
super.writeToChannel(dto);
|
||||
for (Iterator<Inet6Address> iterator = addresses.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
|
||||
for(Inet6Address inet6Address:addresses) {
|
||||
dto.write(ByteBuffer.wrap(inet6Address.getAddress()));
|
||||
}
|
||||
|
||||
for(IPv6SegmentRoutingTLV tlv:tlvs) {
|
||||
IPv6SegmentRoutingTLV.writeIPv6SegmentRoutingTLVToChannel(dto, tlv);
|
||||
}
|
||||
}
|
||||
private int calcExtLength() {
|
||||
int tlvsl=0;
|
||||
for (Iterator<IPv6SegmentRoutingTLV> iterator = tlvs.iterator(); iterator.hasNext();) {
|
||||
IPv6SegmentRoutingTLV tlve = (IPv6SegmentRoutingTLV) iterator.next();
|
||||
for(IPv6SegmentRoutingTLV tlve:tlvs) {
|
||||
tlvsl+=tlve.getLength();
|
||||
}
|
||||
return addresses.size()*16+tlvsl;
|
||||
}
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
int extl=getExtLength();
|
||||
int laste=getLastEntry();
|
||||
@@ -722,6 +732,13 @@ public class IPv6Packet extends NetworkPacket {
|
||||
//System.out.println("SR:"+addr);
|
||||
addresses.add(addr);
|
||||
}
|
||||
tlvs.clear();
|
||||
while(usdl<rl) {
|
||||
IPv6SegmentRoutingTLV tlv=IPv6SegmentRoutingTLV.readIPv6SegmentRoutingTLVFromChannel(din);
|
||||
usdl+=tlv.getLength();
|
||||
tlvs.add(tlv);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
@@ -761,7 +778,20 @@ public class IPv6Packet extends NetworkPacket {
|
||||
public List<IPv6ExtHeader> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public IPv6SegmentRoutingHeader getSRHHeader() {
|
||||
IPv6SegmentRoutingHeader srhh = null;
|
||||
List<IPv6ExtHeader> exhs = headers;
|
||||
for (int j = 0; j < exhs.size(); j++) {
|
||||
IPv6ExtHeader exh = exhs.get(j);
|
||||
if (exh instanceof IPv6SegmentRoutingHeader) {
|
||||
if (((IPv6SegmentRoutingHeader) exh).getRoutingType() == 4) {
|
||||
srhh = (IPv6SegmentRoutingHeader) exh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return srhh;
|
||||
}
|
||||
/*public IPv6DestinationHeader insertDestinationHeader(int index,int extLength) {
|
||||
long ptr;
|
||||
long lth=extLength*8+8;
|
||||
@@ -831,6 +861,18 @@ public class IPv6Packet extends NetworkPacket {
|
||||
protected boolean needEndPosition() {
|
||||
return false;
|
||||
}
|
||||
private AtomicInteger rerouteCounter=new AtomicInteger(0);
|
||||
public AtomicInteger getRerouteCounter() {
|
||||
return rerouteCounter;
|
||||
}
|
||||
private volatile boolean promise=false;
|
||||
public void setPromise(boolean b) {
|
||||
promise=b;
|
||||
}
|
||||
|
||||
public boolean isPromise() {
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ package org.kne.cloud.network.ipv6;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@@ -19,14 +21,22 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.PacketReorder;
|
||||
import org.kne.cloud.network.srv6.SEQSSegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.SRv6PacketReorder;
|
||||
import org.kne.cloud.network.srv6.SRv6PacketSeqMarker;
|
||||
import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV;
|
||||
import org.kne.cloud.network.srv6.SRv6TLV;
|
||||
import org.kne.cloud.network.srv6.TCPTransimitAgent;
|
||||
import org.kne.cloud.network.tun.TUNNetworkDevice;
|
||||
import org.kne.concurrent.DisruptorExecutor;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
@@ -42,11 +52,11 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
|
||||
private Thread tr;
|
||||
|
||||
private ThreadPoolExecutor exc = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
|
||||
private Lock slok=new SpinLock();
|
||||
|
||||
public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu) throws IOException {
|
||||
private SRv6PacketSeqMarker seqm=new SRv6PacketSeqMarker();
|
||||
|
||||
public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu,List<InetAddress>dns) throws IOException {
|
||||
if (tun != null)
|
||||
throw new IllegalStateException("already open!");
|
||||
try {
|
||||
@@ -56,31 +66,42 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
this.hostAddress = hostAddress;
|
||||
if (hostAddress != null)
|
||||
tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength());
|
||||
if(dns!=null) {
|
||||
tun.setDNSAddress(dns);
|
||||
}
|
||||
try {
|
||||
tun.setMTU(mtu);
|
||||
}catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Thread tb = new Thread(() -> {
|
||||
while (true) {
|
||||
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
|
||||
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
try {
|
||||
tun.read(tmp);
|
||||
tmp.flip();
|
||||
//System.out.println(tmp);
|
||||
if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) {
|
||||
while(exc.getQueue().size()>10) {
|
||||
LockSupport.parkNanos(1000000);
|
||||
}
|
||||
exc.execute(() -> {
|
||||
|
||||
HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
try {
|
||||
IPv6Packet ipp = new IPv6Packet();
|
||||
ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu);
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
|
||||
//NetworkPacket.databufferpool_65535.back(tmp);
|
||||
if (con != null) {
|
||||
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
monitor.getOutTrafficAL().addAndGet(ipp.getLength());
|
||||
ipp.setDisposeAfterSend(true);
|
||||
ipp.getPayload().setDisposeAfterSend(true);
|
||||
// ipp.setDisposeAfterSend(true);
|
||||
// ipp.getPayload().setDisposeAfterSend(true);
|
||||
ipp.setPromise(true);
|
||||
if(ipp.getPayload().getProtocolNumber()==6) {
|
||||
seqm.mark(ipp);
|
||||
}
|
||||
con.accept(ipp);
|
||||
} else {
|
||||
ipp.dispose();
|
||||
//ipp.dispose();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -88,10 +109,10 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
|
||||
});
|
||||
}else {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
//NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
//NetworkPacket.databufferpool_65535.back(tmp);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -110,9 +131,16 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
slok.unlock();
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
//NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} else {
|
||||
for(SRv6PacketReorder spr:reorder.values()) {
|
||||
try {
|
||||
spr.runOrdering();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
|
||||
@@ -132,48 +160,84 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
|
||||
private SpeedAndTrafficMonitorDataImpl monitor;
|
||||
|
||||
private ConcurrentHashMap<FlowSession, SRv6PacketReorder> reorder=new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
|
||||
if (tun != null) {/*
|
||||
* AtomicLong seqs=null; try { IPv6RoutingHeader
|
||||
* srhh=getRoutingHeaderFromPacket(pack); if(srhh!=null) { byte[]srd=new
|
||||
* byte[(int) (srhh.getLength()-4)]; srhh.getData().get(4, srd);
|
||||
* IpV6RoutingSRHData srh=IpV6RoutingSRHData.newInstance( srd,0,srd.length);
|
||||
* SRv6StreamSequenceTLV ssqv= getStreamSequenceTLV(srh); if(ssqv!=null)
|
||||
* seqs=new AtomicLong( ssqv.getSequence()); } }catch(IllegalRawDataException
|
||||
* re) {
|
||||
*
|
||||
* }
|
||||
*/
|
||||
|
||||
// System.out.println("add");
|
||||
while(exc.getQueue().size()>10) {
|
||||
LockSupport.parkNanos(1000000);
|
||||
}
|
||||
exc.execute(()->{
|
||||
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
|
||||
if (tun != null) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// System.out.println("rev");
|
||||
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
monitor.getInTrafficAL().addAndGet(pack.getLength());
|
||||
tmp.flip();
|
||||
sendQueue.add(tmp);
|
||||
LockSupport.unpark(tr);
|
||||
IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
|
||||
SEQSSegmentRoutingTLV seqs=null;
|
||||
if(srh!=null) {
|
||||
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
|
||||
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
IPv6SegmentRoutingTLV tlv=l.get(i);
|
||||
if(tlv instanceof SEQSSegmentRoutingTLV) {
|
||||
seqs=(SEQSSegmentRoutingTLV) tlv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sendPacket0(pack,seqs);
|
||||
|
||||
} catch (IOException e) {
|
||||
NetworkPacket.databufferpool_65535.back(tmp);
|
||||
//NetworkPacket.databufferpool_65535.back(tmp);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
pack.disposeAll();
|
||||
});
|
||||
//pack.disposeAll();
|
||||
|
||||
} else {
|
||||
pack.disposeAll();
|
||||
//pack.disposeAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPacket0(IPv6Packet pack,SEQSSegmentRoutingTLV seqs) throws IOException {
|
||||
|
||||
if(seqs!=null&&seqs.isKeepOrder()) {
|
||||
FlowSession fss=pack.getFlowSession();
|
||||
|
||||
|
||||
SRv6PacketReorder newr= new SRv6PacketReorder(new PacketConsumer() {
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet packx) throws IOException {
|
||||
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
packx.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
monitor.getInTrafficAL().addAndGet(packx.getLength());
|
||||
tmp.flip();
|
||||
sendQueue.add(tmp);
|
||||
LockSupport.unpark(tr);
|
||||
}
|
||||
});
|
||||
SRv6PacketReorder olr=reorder.putIfAbsent(fss,newr);
|
||||
if(olr==null) {
|
||||
olr=newr;
|
||||
}
|
||||
olr.put(pack,seqs.getSequence());
|
||||
|
||||
|
||||
}else {
|
||||
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
monitor.getInTrafficAL().addAndGet(pack.getLength());
|
||||
tmp.flip();
|
||||
sendQueue.add(tmp);
|
||||
LockSupport.unpark(tr);
|
||||
}
|
||||
}
|
||||
|
||||
private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) {
|
||||
List<SRv6TLV> stv = srh.getTlvs();
|
||||
for (Iterator iterator = stv.iterator(); iterator.hasNext();) {
|
||||
@@ -199,8 +263,8 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
return sendQueue.size() > 1000;
|
||||
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
|
||||
return sendQueue.size() > 1000*scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -243,6 +307,36 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
|
||||
return hostAddress;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RouteItem> getRouteItems() {
|
||||
List<RouteItem> rlist=new ArrayList<>();
|
||||
|
||||
rlist.add(new RouteItem(new Inet6AddressGroup(this.getAddressGroup().getAddress(), 128),
|
||||
this.getAddressGroup().getAddress(), this, "Direct", 0, 1, null, "D",true));
|
||||
|
||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
|
||||
.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
|
||||
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ri);
|
||||
|
||||
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
|
||||
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ris);
|
||||
|
||||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,13 +63,43 @@ public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
private byte[] cachedRawAddress;
|
||||
public byte[] getRawAddress() {
|
||||
if(cachedRawAddress==null) {
|
||||
return (cachedRawAddress=address.getAddress());
|
||||
}else {
|
||||
return cachedRawAddress;
|
||||
}
|
||||
}
|
||||
private byte[] cachedAndm;
|
||||
private byte[] getAndm(byte[]mask) {
|
||||
if(cachedAndm==null) {
|
||||
return (cachedAndm=and0(mask ,getRawAddress()));
|
||||
}else {
|
||||
return cachedAndm;
|
||||
}
|
||||
}
|
||||
public boolean checkMatch(Inet6Address ia) {
|
||||
byte[]mask=maskTransf[prefixLength];
|
||||
byte[]andj=and0(mask,ia.getAddress());
|
||||
byte[]andm=and0(mask ,address.getAddress());
|
||||
return Arrays.equals(andj,andm);
|
||||
byte[]andm=getAndm(mask);
|
||||
|
||||
return andeq0(mask,ia.getAddress(),andm);
|
||||
}
|
||||
private byte[] and0(byte[] bs, byte[] address2) {
|
||||
public boolean checkMatch(byte[] ia) {
|
||||
byte[]mask=maskTransf[prefixLength];
|
||||
byte[]andm=getAndm(mask);
|
||||
|
||||
return andeq0(mask,ia,andm);
|
||||
}
|
||||
private static boolean andeq0(byte[] bs, byte[] address2, byte[] andm) {
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
if(andm[i]!=(byte) (bs[i]&address2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private static byte[] and0(byte[] bs, byte[] address2) {
|
||||
byte[]rez=new byte[bs.length];
|
||||
for (int i = 0; i < rez.length; i++) {
|
||||
rez[i]=(byte) (bs[i]&address2[i]);
|
||||
@@ -90,4 +120,5 @@ public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
|
||||
address=(Inet6Address) Inet6Address.getByAddress(b);
|
||||
prefixLength=in.read();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,11 +5,14 @@ import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
|
||||
public class Neighbor {
|
||||
private Inet6AddressGroup address;
|
||||
private Inet6AddressGroup locator;
|
||||
private MonitorData monitor;
|
||||
private BandwidthDistributer<Inet6Address> bandwidthDistributer;
|
||||
public MonitorData getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
@@ -19,12 +22,21 @@ public class Neighbor {
|
||||
public Inet6AddressGroup getLocator() {
|
||||
return locator;
|
||||
}
|
||||
|
||||
public BandwidthDistributer<Inet6Address> getBandwidthDistributer() {
|
||||
return bandwidthDistributer;
|
||||
}
|
||||
public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) {
|
||||
super();
|
||||
this.address = address;
|
||||
this.locator = locator;
|
||||
this.monitor = monitor;
|
||||
}
|
||||
public Neighbor(Inet6AddressGroup peerAddress, Inet6AddressGroup remoteVaddr, QueueingMonitorDataImpl monitor2,
|
||||
BandwidthDistributer<Inet6Address> bandwidthDistributer) {
|
||||
this(peerAddress,remoteVaddr,monitor2);
|
||||
this.bandwidthDistributer=bandwidthDistributer;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]";
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.kne.cloud.network.monitor.DelayMonitorData;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
|
||||
public class RouteItem implements Comparable<RouteItem>{
|
||||
public class RouteItem implements Comparable<RouteItem>,Cloneable{
|
||||
private Inet6AddressGroup destination;
|
||||
private Inet6Address nexthop;
|
||||
private IPv6NetworkLink destlink;
|
||||
@@ -20,6 +20,7 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
private long cost;
|
||||
private String flag;
|
||||
private MonitorData monitor;
|
||||
private boolean isLoopback;
|
||||
public String getFlag() {
|
||||
return flag;
|
||||
}
|
||||
@@ -44,7 +45,7 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
&& pre == other.pre && Objects.equals(proto, other.proto);
|
||||
}
|
||||
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
||||
long cost,String flag) {
|
||||
long cost,String flag,boolean isLoopback) {
|
||||
super();
|
||||
this.destination = destination;
|
||||
this.nexthop = nexthop;
|
||||
@@ -53,9 +54,10 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
this.pre = pre;
|
||||
this.cost = cost;
|
||||
this.flag=flag;
|
||||
this.isLoopback=isLoopback;
|
||||
}
|
||||
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
|
||||
long cost,MonitorData monitor,String flag) {
|
||||
long cost,MonitorData monitor,String flag,boolean isLoopback) {
|
||||
super();
|
||||
this.destination = destination;
|
||||
this.nexthop = nexthop;
|
||||
@@ -65,6 +67,7 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
this.cost = cost;
|
||||
this.monitor=monitor;
|
||||
this.flag=flag;
|
||||
this.isLoopback=isLoopback;
|
||||
}
|
||||
public Inet6AddressGroup getDestination() {
|
||||
return destination;
|
||||
@@ -81,6 +84,9 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
public int getPre() {
|
||||
return pre;
|
||||
}
|
||||
public boolean isLoopback() {
|
||||
return isLoopback;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop().getHostAddress()+"\t"+getDestlink().getName();
|
||||
@@ -91,6 +97,9 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
public boolean checkMatch(Inet6Address ia) {
|
||||
return destination.checkMatch(ia);
|
||||
}
|
||||
public boolean checkMatch(byte[] ia) {
|
||||
return destination.checkMatch(ia);
|
||||
}
|
||||
@Override
|
||||
public int compareTo(RouteItem o) {
|
||||
int v1=destination.compareTo(o.destination);
|
||||
@@ -105,7 +114,35 @@ public class RouteItem implements Comparable<RouteItem>{
|
||||
if(monitor==null||o.monitor==null||(!(monitor instanceof DelayMonitorData))||(!(o.monitor instanceof DelayMonitorData)))
|
||||
return v3;
|
||||
if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl))
|
||||
return Long.compare(((DelayMonitorData)monitor).getOutDelay(), ((DelayMonitorData)o.monitor).getOutDelay());
|
||||
return Long.compare(((DelayMonitorData)monitor).getOutDelay()+((QueueingMonitorDataImpl)monitor).getQueueingDelay(), ((DelayMonitorData)o.monitor).getOutDelay()+((QueueingMonitorDataImpl)o.monitor).getQueueingDelay());
|
||||
return Long.compare(outDelay, o.outDelay);
|
||||
return Long.compare(outDelay+queueingDelay, o.outDelay+o.queueingDelay);
|
||||
}
|
||||
@Override
|
||||
public Object clone() {
|
||||
try {
|
||||
RouteItem ri=(RouteItem) super.clone();
|
||||
if(monitor!=null)
|
||||
ri.monitor=(MonitorData) monitor.clone();
|
||||
return ri;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
long outDelay;
|
||||
long queueingDelay;
|
||||
public void preSort() {
|
||||
if(monitor!=null) {
|
||||
outDelay=((DelayMonitorData)monitor).getOutDelay();
|
||||
if(monitor instanceof QueueingMonitorDataImpl) {
|
||||
queueingDelay=((QueueingMonitorDataImpl)monitor).getQueueingDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean ECMPequals(RouteItem prevr) {
|
||||
return prevr.getDestination().getPrefixLength()==getDestination().getPrefixLength()&&prevr.getPre()==getPre()&&prevr.getCost()==getCost();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
|
||||
public class TLV extends NetworkPacket{
|
||||
|
||||
private int headerLength=2;
|
||||
|
||||
public int getHeaderLength() {
|
||||
return headerLength;
|
||||
}
|
||||
|
||||
private boolean isDefault;
|
||||
|
||||
protected volatile ByteBuffer header;
|
||||
|
||||
private ByteBuffer data;
|
||||
|
||||
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return headerLength+(isDefault?data.limit():0);
|
||||
}
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
setDataLength(data.limit());
|
||||
}
|
||||
header.limit(headerLength);
|
||||
dto.write(header.slice(0,header.limit()));
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
dto.write(data.slice(0, data.limit()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
header.limit(1);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
if(headerLength>1) {
|
||||
header.limit(2);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
}
|
||||
header.flip();
|
||||
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data.clear();
|
||||
data.limit(getDataLength());
|
||||
while(data.hasRemaining()){
|
||||
if(din.read(data)==-1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
data.flip();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needEndPosition() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return header.get(0)&0xff;
|
||||
}
|
||||
public void setType(int type) {
|
||||
header.put(0,(byte) type);
|
||||
}
|
||||
|
||||
public int getDataLength() {
|
||||
return header.get(1)&0xff;
|
||||
}
|
||||
|
||||
public void setDataLength(int dataLength) {
|
||||
header.put(1,(byte) dataLength);
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,15 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
|
||||
private static final int HEADER_LENGTH=28;
|
||||
private static final int HEADER_LENGTH=35;
|
||||
|
||||
public ACKTPacket(int sport,int dport,long number,boolean avaliable,boolean congress,long rcvSpeed,int sendcount) {
|
||||
public ACKTPacket(int sport,int dport,long number,long avaliableRcvWindow,boolean congress,long rcvSpeed,int sendcount) {
|
||||
super(ACKT,HEADER_LENGTH);
|
||||
klalbHeader.putInt(sport);
|
||||
klalbHeader.putInt(dport);
|
||||
klalbHeader.putLong(number);
|
||||
klalbHeader.put((byte) sendcount);
|
||||
klalbHeader.put((byte) (avaliable?1:0));
|
||||
klalbHeader.putLong(avaliableRcvWindow);
|
||||
klalbHeader.put((byte) (congress?1:0));
|
||||
klalbHeader.putLong(rcvSpeed);
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable();
|
||||
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] avaliable:"+getAvaliableRcvWindow();
|
||||
}
|
||||
|
||||
public int getSport() {
|
||||
@@ -41,7 +41,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
}
|
||||
|
||||
public boolean isCongress() {
|
||||
return klalbHeader.get(19)!=0;
|
||||
return klalbHeader.get(26)!=0;
|
||||
}
|
||||
|
||||
public int getDport() {
|
||||
@@ -52,8 +52,8 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
return klalbHeader.getLong(9);
|
||||
}
|
||||
|
||||
public boolean isAvaliable() {
|
||||
return klalbHeader.get(18)!=0;
|
||||
public long getAvaliableRcvWindow() {
|
||||
return klalbHeader.getLong(18);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,6 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
|
||||
return klalbHeader.getInt(17);
|
||||
}
|
||||
public long getRcvSpeed() {
|
||||
return klalbHeader.getLong(20);
|
||||
return klalbHeader.getLong(27);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class ADDLINESPacket extends KLALBPacket {
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
byte[]bta=lines.getBytes(Charset.forName("UTF-8"));
|
||||
klalbHeader.putChar(1,(char) bta.length);
|
||||
super.writeToChannel(dto);
|
||||
@@ -49,7 +49,7 @@ public class ADDLINESPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
int lth=klalbHeader.getChar(1);
|
||||
byte[]b=new byte[lth];
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public abstract class AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
|
||||
private AtomicLong[] inputTrafficCounters;
|
||||
private AtomicLong[] outputTrafficCounters;
|
||||
private AtomicLong[] inputPacketsCounters;
|
||||
private AtomicLong[] outputPacketsCounters;
|
||||
@Override
|
||||
public void setOutputPacketsCounters(AtomicLong[] outCounter) {
|
||||
outputPacketsCounters=outCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputPacketsCounters(AtomicLong[] inCounter) {
|
||||
inputPacketsCounters=inCounter;
|
||||
|
||||
}
|
||||
@Override
|
||||
public void setOutputTrafficCounters(AtomicLong[] outCounter) {
|
||||
this.outputTrafficCounters=outCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputTrafficCounters(AtomicLong[] inCounter) {
|
||||
this.inputTrafficCounters=inCounter;
|
||||
}
|
||||
|
||||
public AtomicLong[] getInputTrafficCounters() {
|
||||
return inputTrafficCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getOutputTrafficCounters() {
|
||||
return outputTrafficCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getInputPacketsCounters() {
|
||||
return inputPacketsCounters;
|
||||
}
|
||||
|
||||
public AtomicLong[] getOutputPacketsCounters() {
|
||||
return outputPacketsCounters;
|
||||
}
|
||||
|
||||
protected void incOutput(int packetLength) {
|
||||
if(outputTrafficCounters!=null) {
|
||||
for(AtomicLong al:outputTrafficCounters) {
|
||||
al.addAndGet(packetLength);
|
||||
}
|
||||
}
|
||||
if(outputPacketsCounters!=null) {
|
||||
for(AtomicLong al:outputPacketsCounters) {
|
||||
al.incrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void incInput(int packetLength) {
|
||||
if(inputTrafficCounters!=null) {
|
||||
for(AtomicLong al:inputTrafficCounters) {
|
||||
al.addAndGet(packetLength);
|
||||
}
|
||||
}
|
||||
if(inputPacketsCounters!=null) {
|
||||
for(AtomicLong al:inputPacketsCounters) {
|
||||
al.incrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
ByteBuffer dataWrite=NetworkPacket.bufferAllocator.allocate((int) kp.getLength());
|
||||
//dataWrite.clear();
|
||||
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel( dataWrite), kp);
|
||||
dataWrite.flip();
|
||||
writePacket(dataWrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
ByteBuffer buffer=readPacket();
|
||||
if(buffer==null) {
|
||||
return null;
|
||||
}
|
||||
return KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(buffer));
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
/*
|
||||
public class ByteBufferPool {
|
||||
private Queue<ByteBuffer> rec;
|
||||
private int maxcount;
|
||||
private int length;
|
||||
private boolean direct;
|
||||
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
this.direct=direct;
|
||||
rec=new ConcurrentLinkedQueue<ByteBuffer>();
|
||||
}
|
||||
public ByteBufferPool(int maxcount, int length) {
|
||||
this(maxcount, length, true);
|
||||
}
|
||||
public void back(ByteBuffer b) {
|
||||
if(b.capacity()!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
b.clear();
|
||||
rec.offer(b);
|
||||
}
|
||||
public ByteBuffer borrow() {
|
||||
ByteBuffer b=rec.poll();
|
||||
if(b==null) {
|
||||
if(direct)
|
||||
b=ByteBuffer.allocateDirect(length);
|
||||
else
|
||||
b=ByteBuffer.allocate(length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
public class ByteBufferPool {
|
||||
private ByteBuffer[]rec;
|
||||
private volatile int pos=0;
|
||||
private Lock lock=new SpinLock();
|
||||
|
||||
private int maxcount;
|
||||
private int length;
|
||||
private int mcj;
|
||||
private boolean direct;
|
||||
public ByteBufferPool(int maxcount, int length,boolean direct) {
|
||||
super();
|
||||
this.maxcount = maxcount;
|
||||
this.length = length;
|
||||
this.direct=direct;
|
||||
rec=new ByteBuffer[maxcount];
|
||||
mcj=rec.length-1;
|
||||
}
|
||||
public ByteBufferPool(int maxcount, int length) {
|
||||
this(maxcount, length, true);
|
||||
}
|
||||
public void back(ByteBuffer b) {
|
||||
if(b.capacity()!=length)
|
||||
throw new IllegalArgumentException("wrong length");
|
||||
b.clear();
|
||||
lock.lock();
|
||||
try {
|
||||
if(pos<mcj)
|
||||
rec[++pos]= b;
|
||||
}finally{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
public ByteBuffer borrow() {
|
||||
ByteBuffer b=null;
|
||||
lock.lock();
|
||||
try {
|
||||
if(pos>0) {
|
||||
b=rec[pos--];
|
||||
//rec[pos--]=null;
|
||||
}
|
||||
}finally{
|
||||
lock.unlock();
|
||||
}
|
||||
if(b==null) {
|
||||
if(direct)
|
||||
b=ByteBuffer.allocateDirect(length);
|
||||
else
|
||||
b=ByteBuffer.allocate(length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
public int getMaxCount() {
|
||||
return maxcount;
|
||||
}
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,11 @@ package org.kne.cloud.network.klalb;
|
||||
|
||||
public class CONST {
|
||||
public static final String klalb="KLALB";
|
||||
public static final String klalbver="3.0";
|
||||
public static final String klalbver="3.2";
|
||||
public static final int bversion=3;
|
||||
public static final int sversion=0;
|
||||
public static final int sversion=1;
|
||||
public static final int itemwidth = 720;
|
||||
public static final int linepanelheight = 45;
|
||||
public static final int settingheight = 30;
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
klalbHeader.putChar((char) 0);
|
||||
|
||||
//dataBuffer.limit(mtulimit);
|
||||
dataBuffer=ByteBuffer.allocate(mtulimit);
|
||||
dataBuffer=NetworkPacket.bufferAllocator.allocate(mtulimit);
|
||||
}
|
||||
|
||||
public int getSendcount() {
|
||||
@@ -100,7 +100,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.put(17, (byte) getSendCounter());
|
||||
klalbHeader.putChar(18, (char) dataBuffer.limit());
|
||||
super.writeToChannel(dto);
|
||||
@@ -109,13 +109,13 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
numberc=Long.MIN_VALUE;
|
||||
int limit=klalbHeader.getChar(18);
|
||||
//dataBuffer.clear();
|
||||
//dataBuffer.limit();
|
||||
dataBuffer=ByteBuffer.allocate(limit);
|
||||
dataBuffer=NetworkPacket.bufferAllocator.allocate(limit);
|
||||
while(dataBuffer.hasRemaining()){
|
||||
if(din.read(dataBuffer)==-1) {
|
||||
throw new EOFException();
|
||||
@@ -124,12 +124,5 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
|
||||
dataBuffer.flip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/*ByteBuffer datan=dataBuffer;
|
||||
dataBuffer=null;
|
||||
NetworkPacket.databufferpool_65535.back(datan);*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -125,12 +125,14 @@ import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.kne.cloud.network.DatagramServerSocket;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
|
||||
public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
public class DatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -145,17 +147,20 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||
private DataOutputStream dos=new DataOutputStream(bos);
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
/*@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
//System.out.println(" TX:"+kp);
|
||||
KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||
|
||||
byte[]bt=bos.toByteArray();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
||||
ds.send(dp);
|
||||
bos.reset();
|
||||
}
|
||||
|
||||
private byte[]bc=new byte[65535];
|
||||
DataInputStream dis;
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
KLALBPacket kp=null;
|
||||
do {
|
||||
if(dis==null) {
|
||||
@@ -176,8 +181,37 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
//System.out.println(" RX:"+kp);
|
||||
}while(true);
|
||||
return kp;
|
||||
}*/
|
||||
|
||||
|
||||
byte[]b=new byte[65536];
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
int length=kp.remaining();
|
||||
incOutput(length);
|
||||
kp.get(b,0,length);
|
||||
DatagramPacket dp=new DatagramPacket(b,length);
|
||||
ds.send(dp);
|
||||
}
|
||||
|
||||
byte[]c=new byte[65536];
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
DatagramPacket dp;
|
||||
if(ds instanceof DatagramServerSocket.SubDatagramSocket) {
|
||||
dp=((DatagramServerSocket.SubDatagramSocket) ds).receive();
|
||||
}else {
|
||||
dp=new DatagramPacket(c, c.length);
|
||||
ds.receive(dp);
|
||||
}
|
||||
incInput(dp.getLength());
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(dp.getLength());
|
||||
bbf.put(dp.getData(),0,dp.getLength());
|
||||
bbf.flip();
|
||||
return bbf;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
ds.close();
|
||||
@@ -200,10 +234,7 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
byte[]bt=bos.toByteArray();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bt.length);
|
||||
ds.send(dp);
|
||||
bos.reset();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -211,4 +242,6 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class IPSequence {
|
||||
private UUID uuid;
|
||||
private boolean isPromise;
|
||||
|
||||
|
||||
public IPSequence(UUID uuid, boolean isPromise) {
|
||||
super();
|
||||
this.uuid = uuid;
|
||||
this.isPromise = isPromise;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public boolean isPromise() {
|
||||
return isPromise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPSequence [uuid=" + uuid + ", isPromise=" + isPromise + "]";
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(uuid);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IPSequence other = (IPSequence) obj;
|
||||
return Objects.equals(uuid, other.uuid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,26 +10,6 @@ import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
private static final int HEADER_LENGTH=9;
|
||||
@Override
|
||||
public boolean isSomeDisposed() {
|
||||
return super.isDisposed()||ipv6Packet.isSomeDisposed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void lockAll() {
|
||||
super.lockAll();
|
||||
ipv6Packet.lockAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void unlockAll() {
|
||||
ipv6Packet.unlockAll();
|
||||
super.unlockAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@@ -56,12 +36,6 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
super(bb,HEADER_LENGTH);
|
||||
this.ipv6Packet=new IPv6Packet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeAll() {
|
||||
super.disposeAll();
|
||||
ipv6Packet.disposeAll();
|
||||
}
|
||||
|
||||
public IPv6Packet getIPv6Packet() {
|
||||
return ipv6Packet;
|
||||
@@ -78,24 +52,16 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.putLong(1, ipv6Packet.getLength());
|
||||
super.writeToChannel(dto);
|
||||
ipv6Packet.writeToChannel(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
super.readFromChannel(din,length);
|
||||
ipv6Packet.readFromChannel(din, klalbHeader.getLong(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void doDisposeAfterSend() {
|
||||
super.doDisposeAfterSend();
|
||||
ipv6Packet.doDisposeAfterSend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,14 +56,18 @@ import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm;
|
||||
import org.kne.concurrent.DisruptorExecutor;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.io.KNEChannels;
|
||||
import org.pcap4j.packet.IpV6Packet.IpV6Header;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public class KLALBController {
|
||||
|
||||
|
||||
@@ -80,6 +84,12 @@ public class KLALBController {
|
||||
|
||||
private static List<IPMulticastDiscovery> ipmd=new ArrayList<>();
|
||||
|
||||
private List<InetAddress>dnsAddresses=new ArrayList<>();
|
||||
|
||||
public List<InetAddress> getDnsAddresses() {
|
||||
return dnsAddresses;
|
||||
}
|
||||
|
||||
private Timer twk=new Timer("网卡检测扫描计时器", true);
|
||||
{
|
||||
|
||||
@@ -210,48 +220,49 @@ public class KLALBController {
|
||||
continue;
|
||||
}
|
||||
if(networkInterface.isUp()) {
|
||||
boolean b=true;
|
||||
|
||||
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||
loop:while (ei.hasMoreElements()) {
|
||||
InetAddress bidr = (InetAddress) ei.nextElement();
|
||||
|
||||
for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
|
||||
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
|
||||
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())) {
|
||||
b=false;
|
||||
break;
|
||||
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())&&bidr.equals(ipMulticastDiscovery.getBind().getAddress())) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
if(b) {
|
||||
/*InetAddress bidr=null;
|
||||
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
|
||||
while (ei.hasMoreElements()) {
|
||||
InetAddress inetAddress = (InetAddress) ei.nextElement();
|
||||
if(inetAddress instanceof Inet6Address) {
|
||||
Inet6Address i6=(Inet6Address) inetAddress;
|
||||
if(i6.getHostAddress().startsWith("fe80")) {
|
||||
bidr=i6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(bidr!=null)*/
|
||||
|
||||
|
||||
|
||||
try {
|
||||
InetAddress bidr=InetAddress.getByName("::0");
|
||||
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable);
|
||||
//InetAddress bidr=InetAddress.getByName("::0");
|
||||
|
||||
if(bidr instanceof Inet6Address) {
|
||||
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable,10000L);
|
||||
ipd.setCon((mpa)->{
|
||||
//System.out.println("添加本地IPv6链路:"+mpa);
|
||||
addRemoteLines(mpa);
|
||||
try {
|
||||
if(!checkIsSelf(mpa))
|
||||
addRemoteLines(mpa);
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
});
|
||||
ipd.start();
|
||||
ipmd.add(ipd);
|
||||
|
||||
bidr=InetAddress.getByName("0.0.0.0");
|
||||
IPMulticastDiscovery ipd2=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("224.0.0.86"),DISCOVERY_PORT), networkInterface,selflineTable);
|
||||
}else if(bidr instanceof Inet4Address) {
|
||||
//bidr=InetAddress.getByName("0.0.0.0");
|
||||
IPMulticastDiscovery ipd2=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("224.0.0.86"),DISCOVERY_PORT), networkInterface,selflineTable,10000L);
|
||||
ipd2.setCon((mpa)->{
|
||||
//System.out.println("添加本地IPv4链路:"+mpa);
|
||||
addRemoteLines(mpa);
|
||||
try {
|
||||
if(!checkIsSelf(mpa))
|
||||
addRemoteLines(mpa);
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
});
|
||||
ipd2.start();
|
||||
ipmd.add(ipd2);
|
||||
|
||||
}
|
||||
System.out.println("添加网卡:"+networkInterface);
|
||||
}catch(BindException e) {
|
||||
//e.printStackTrace();
|
||||
@@ -259,8 +270,11 @@ public class KLALBController {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +284,11 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean checkIsSelf(MultipurposeSocketAddress inetAddress) throws UnknownHostException {
|
||||
|
||||
return inetAddress.getInetAddress().isAnyLocalAddress()||inetAddress.getInetAddress().isLoopbackAddress()||selflineTable.contains(inetAddress);
|
||||
}
|
||||
}, 2000, 2000);
|
||||
}
|
||||
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
|
||||
@@ -326,10 +345,10 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
|
||||
private Inet6AddressGroup self;
|
||||
//private Inet6AddressGroup self;
|
||||
|
||||
public Inet6Address getSelf() {
|
||||
return self.getAddress();
|
||||
public Inet6AddressGroup getSelf() {
|
||||
return srv6Router.getLocator();
|
||||
}
|
||||
private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
|
||||
private ReadWriteLock lineslock=new ReentrantReadWriteLock();
|
||||
@@ -339,11 +358,16 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
private PortBinder streamPortBinder=new PortBinder(this);
|
||||
|
||||
private PortBinder rawPortBinder=new PortBinder(this);
|
||||
|
||||
protected PortBinder getStreamPortBinder() {
|
||||
return streamPortBinder;
|
||||
}
|
||||
|
||||
|
||||
public PortBinder getRawPortBinder() {
|
||||
return rawPortBinder;
|
||||
}
|
||||
|
||||
public void reconnectImmediately() {
|
||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||
@@ -380,7 +404,8 @@ public class KLALBController {
|
||||
|
||||
}
|
||||
|
||||
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
|
||||
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {lineslock.writeLock().lock();
|
||||
try {
|
||||
List<KLALBRemoteLine>added=new ArrayList<>();
|
||||
try {
|
||||
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
|
||||
@@ -419,6 +444,9 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
return added;
|
||||
}finally {
|
||||
lineslock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
|
||||
|
||||
@@ -477,15 +505,15 @@ public class KLALBController {
|
||||
}
|
||||
|
||||
public void addRemoteLine(KLALBRemoteLine krs) {
|
||||
lineslock.writeLock().lock();
|
||||
try {
|
||||
krs.setPacketReceiver(prc);
|
||||
krs.setKlalbController(this);
|
||||
krs.setLocalVaddrSupplier(()->{return self;});
|
||||
krs.setLocalVaddrSupplier(()->{return getSelf();});
|
||||
krs.startIO();
|
||||
String selflineTable=generateSelfLineTable();
|
||||
if(selflineTable!=null&&!selflineTable.equals(""))
|
||||
krs.sendPacket(new ADDLINESPacket(selflineTable));
|
||||
lineslock.writeLock().lock();
|
||||
try {
|
||||
lines.add(krs);
|
||||
}finally {
|
||||
lineslock.writeLock().unlock();
|
||||
@@ -502,16 +530,12 @@ public class KLALBController {
|
||||
}
|
||||
return sbd.toString();
|
||||
}
|
||||
|
||||
public KLALBController(Inet6Address self) {
|
||||
this.self =new Inet6AddressGroup(self, PREFIX);
|
||||
loadSRv6ProtocolStack();
|
||||
}
|
||||
|
||||
private class KLALBProtocolPacketConsumer implements PacketConsumer{
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet packx) throws IOException {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
//HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
|
||||
/*System.out.println("RCV:"+packx.getPayload().getData());
|
||||
byte[]b=new byte[packx.getPayload().getData().limit()];
|
||||
@@ -539,18 +563,18 @@ public class KLALBController {
|
||||
}
|
||||
}
|
||||
}
|
||||
packx.dispose();
|
||||
});
|
||||
//packx.dispose();
|
||||
//});
|
||||
}
|
||||
|
||||
}
|
||||
private void loadSRv6ProtocolStack() {
|
||||
srv6Router=new SRv6Router(self);
|
||||
private void loadSRv6ProtocolStack(Inet6AddressGroup selfx,boolean enableVirtualAdapter) {
|
||||
srv6Router=new SRv6Router(selfx);
|
||||
if(enableVirtualAdapter)
|
||||
try {
|
||||
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU);
|
||||
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU, dnsAddresses);
|
||||
tunlink.setMonitor(datatMonitor);
|
||||
srv6Router.getLinkTabel().add(tunlink);
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -558,8 +582,19 @@ public class KLALBController {
|
||||
srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer());
|
||||
System.out.println("SRv6协议栈已加载");
|
||||
}
|
||||
|
||||
public KLALBController() {
|
||||
this(true,null);
|
||||
}
|
||||
public KLALBController (Inet6Address self) {
|
||||
this(self,true,null);
|
||||
}
|
||||
public KLALBController(Inet6Address self,boolean enableVirtualAdapter,List<InetAddress> dnsaddr) {
|
||||
this.dnsAddresses=dnsaddr;
|
||||
Inet6AddressGroup selfg =new Inet6AddressGroup(self, PREFIX);
|
||||
loadSRv6ProtocolStack(selfg,enableVirtualAdapter);
|
||||
}
|
||||
public KLALBController(boolean enableVirtualAdapter,List<InetAddress> dnsaddr) {
|
||||
this.dnsAddresses=dnsaddr;
|
||||
SecureRandom sc=new SecureRandom();
|
||||
byte[]v=new byte[16];
|
||||
sc.nextBytes(v);
|
||||
@@ -569,27 +604,31 @@ public class KLALBController {
|
||||
v[3]=1;
|
||||
v[14]=0;
|
||||
v[15]=1;
|
||||
Inet6AddressGroup selfx=null;
|
||||
try {
|
||||
this.self=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
|
||||
selfx=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
loadSRv6ProtocolStack();
|
||||
loadSRv6ProtocolStack(selfx,enableVirtualAdapter);
|
||||
}
|
||||
|
||||
public KLALBController(List<InetAddress> daddr) {
|
||||
this(true,daddr);
|
||||
}
|
||||
|
||||
public KLALBController(Inet6Address self, List<InetAddress> daddr) {
|
||||
this(self,true,daddr);
|
||||
}
|
||||
|
||||
public KLALBController(boolean enableVirtualAdapter) {
|
||||
this(enableVirtualAdapter,null);
|
||||
}
|
||||
|
||||
protected KLALBVirtualSocketImpl createVirtualImpl() {
|
||||
return new KLALBVirtualSocketImpl(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet)
|
||||
throws IOException {
|
||||
sendPacketToLinkAddress(addr, packet, 1);
|
||||
}
|
||||
|
||||
private SRv6Router srv6Router;
|
||||
|
||||
|
||||
@@ -603,7 +642,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
|
||||
//Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
|
||||
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
|
||||
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
|
||||
if(klalbRemoteLine.isClosed()) {
|
||||
@@ -615,20 +654,20 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
}
|
||||
}else {
|
||||
if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
|
||||
if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
|
||||
/* if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
|
||||
lines2.get(klalbRemoteLine.getRemoteVaddr()).getEntries().add(klalbRemoteLine);
|
||||
}else {
|
||||
ArrayList<KLALBRemoteLine>al1=new ArrayList<>();
|
||||
al1.add(klalbRemoteLine);
|
||||
lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1));
|
||||
}
|
||||
}*/
|
||||
if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) {
|
||||
srv6Router.getLinkTabel().add(klalbRemoteLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
|
||||
/*for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>) iterator.next();
|
||||
List<KLALBRemoteLine> lineList=klalbRemoteLine.getValue().getEntries();
|
||||
lineList.forEach((r)->{
|
||||
@@ -641,7 +680,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
}
|
||||
|
||||
}
|
||||
KLALBController.this.lines2=lines2;
|
||||
KLALBController.this.lines2=lines2;*/
|
||||
if(srv6Router!=null) {
|
||||
srv6Router.getLinkTabel().removeIf((v)->{
|
||||
return (v instanceof KLALBRemoteLine)&&(!v.isUp());
|
||||
@@ -649,7 +688,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
srv6Router.updateRouteTabel();
|
||||
}
|
||||
}
|
||||
}, 1, 1);
|
||||
}, 2, 2);
|
||||
}
|
||||
/*private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
|
||||
List<KLALBRemoteLine> l=new ArrayList();
|
||||
@@ -675,122 +714,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
lines2.put(addr, l);
|
||||
}
|
||||
}*/
|
||||
private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet, int count)
|
||||
throws IOException {
|
||||
if(packet==null)
|
||||
throw new NullPointerException("packet is null!");
|
||||
//TimeDebugger tdb=new TimeDebugger();
|
||||
|
||||
|
||||
//tdb.putTime("start");
|
||||
packet.genseq();
|
||||
/*loop:while(true) {
|
||||
if(packet.isDisposed())
|
||||
return;
|
||||
List<KLALBRemoteLine> lines2x;
|
||||
|
||||
lines2x=lines2.get(addr);
|
||||
|
||||
if (lines2x == null || lines2x.isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
|
||||
int count0 = Math.min(count, lines2x.size());
|
||||
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(!packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<10) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<10) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
LockSupport.parkNanos(50000);
|
||||
//tdb.putTime("sendfailed");
|
||||
}*/
|
||||
//tdb.putTime("sendsuccess");
|
||||
//tdb.print();
|
||||
|
||||
/* List<KLALBRemoteLine> lines2x;
|
||||
lines2x=lines2.get(addr);
|
||||
|
||||
if (lines2x == null || lines2x.isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
KLALBRemoteLine kr= lines2x.get(0);
|
||||
kr.sendPacket(packet);
|
||||
packet.getSendRecord().add(kr);*/
|
||||
|
||||
/*loop:while(true) {
|
||||
if(packet.isDisposed())
|
||||
return;
|
||||
DWRRLoadingBalanceAlgorithm<KLALBRemoteLine> dwrlines2x;
|
||||
|
||||
dwrlines2x=lines2.get(addr);
|
||||
|
||||
if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) {
|
||||
throw new NoRouteToHostException("address unreachable: " + addr);
|
||||
}
|
||||
|
||||
List<KLALBRemoteLine>lines2x=dwrlines2x.roundEntriesList();
|
||||
|
||||
int count0 = Math.min(count, lines2x.size());
|
||||
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(!packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<5) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < lines2x.size(); i++) {
|
||||
KLALBRemoteLine krst =lines2x.get(i);
|
||||
if(krst.getMonitor().getState()==MonitorData.ONLINE)
|
||||
if(packet.getSendRecord().contains(krst)) {
|
||||
if(krst.getQueue().size()<5) {
|
||||
packet.getSendRecord().add(krst);
|
||||
//System.out.println(krst);
|
||||
krst.sendPacket(packet);
|
||||
count0--;
|
||||
if (count0 <= 0)
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
LockSupport.parkNanos(50000);
|
||||
//tdb.putTime("sendfailed");
|
||||
}*/
|
||||
}
|
||||
//private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
@@ -804,11 +728,8 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
packet.getDisposeLock().lock();
|
||||
try {
|
||||
if(packet.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(showpacket)
|
||||
System.out.println("KLALB_TX:"+packet);
|
||||
|
||||
@@ -816,10 +737,15 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(flowlabel);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(self.getAddress());
|
||||
ipv.setSourceAddress(getSelf().getAddress());
|
||||
ipv.setDestinationAddress(addr);
|
||||
ipv.setPriority(packet.getPriority());
|
||||
if(packet instanceof DATATPacket) {
|
||||
ipv.setPromise(true);
|
||||
}
|
||||
ipv.enableECN();
|
||||
/* if(b)
|
||||
ipv.markCE();*/
|
||||
ipv.setPayload(packet);
|
||||
//System.out.println(ipv.getPayload().getProtocolNumber());
|
||||
/*System.out.println("SND:"+ipv.getPayload().getData());
|
||||
@@ -828,13 +754,12 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
System.out.println(Arrays.toString(b));*/
|
||||
//packet.getSendRecord().add(null);
|
||||
packet.incSendCounter();
|
||||
}finally {
|
||||
packet.getDisposeLock().unlock();
|
||||
}
|
||||
|
||||
packet.putTimePassport("packedInIPv6");
|
||||
packet.printPassport();
|
||||
ipv.putTimePassport("packed");
|
||||
srv6Router.putProtocolNumberPacketAndInsertSRH(ipv);
|
||||
srv6Router.insertSRHandRoutePacket(ipv);
|
||||
//srv6Router.putProtocolNumberPacketAndInsertSRHAsync(ipv);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -869,7 +794,11 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
|
||||
try {
|
||||
BandwidthDistributer<PortPair> bdr= bandwidthDistrmap.get(targetaAddress);
|
||||
if(bdr==null) {
|
||||
bandwidthDistrmap.put(targetaAddress, bdr=new BandwidthDistributer<>(1024*20000L*1024));
|
||||
bdr=new BandwidthDistributer<>(1024*20000L*1024);
|
||||
bdr.setTotalRequestUpdateConsumer((treq)->{
|
||||
KLALBRoutingProtocol krp= srv6Router.getKlalbRouteProtol();
|
||||
krp.updateTotalRequestBandwidth(targetaAddress,treq);});
|
||||
bandwidthDistrmap.put(targetaAddress, bdr);
|
||||
}
|
||||
|
||||
bdr.setDistrUpdateConsumer(portp, updateConsumer);
|
||||
@@ -920,7 +849,6 @@ private List<MultipurposeSocketAddress> listens=new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*@Override
|
||||
public void listen(MultipurposeSocketAddress msa) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
@@ -8,10 +8,18 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.net.Inet6Address;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBInputStream extends DataInputStream {
|
||||
private ReadableByteChannel channel;
|
||||
public KLALBInputStream(InputStream in) throws IOException {
|
||||
super(in);
|
||||
channel=Channels.newChannel(in);
|
||||
byte[]b=new byte[5];
|
||||
readFully(b);
|
||||
String s=new String(b,"ascii");
|
||||
@@ -23,8 +31,16 @@ public class KLALBInputStream extends DataInputStream {
|
||||
if(bv!=CONST.bversion)
|
||||
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V"+CONST.klalbver);
|
||||
}
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
int len=readInt();
|
||||
return KLALBPacket.readKLALBPacketFromStream(this);
|
||||
}
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
int len=readInt();
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(len);
|
||||
bbf.limit(len);
|
||||
KNEChannels.readFully(channel, bbf);
|
||||
return bbf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.kne.cloud.network.ipv6.RouteItem;
|
||||
import org.kne.cloud.network.klalb.ui.KLALBStateGUI2;
|
||||
import org.kne.cloud.network.klalb.ui.UIEnv;
|
||||
import org.kne.cloud.network.perf.Kperf;
|
||||
import org.kne.cloud.network.perf.MemcpyBenchmark;
|
||||
import org.kne.cloud.network.perf.NodeBenchmark;
|
||||
import org.kne.debug.Debuger;
|
||||
|
||||
public class KLALBMain {
|
||||
@@ -37,7 +39,7 @@ public class KLALBMain {
|
||||
|
||||
KLALBProxySystem kpcje=new KLALBProxySystem();
|
||||
kpcje.loadConfigJson(configJson);
|
||||
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getHostAddress());
|
||||
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getAddress().getHostAddress());
|
||||
try {
|
||||
openGUI(kpcje);
|
||||
}catch(RuntimeException e) {
|
||||
@@ -152,10 +154,40 @@ public class KLALBMain {
|
||||
System.out.println("请输入测速服务端地址:端口!");
|
||||
}
|
||||
|
||||
break;
|
||||
case "memcpy":
|
||||
System.out.println("数组拷贝测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark. testArrayCopySpeed(256*1024*1024);
|
||||
}
|
||||
System.out.println("Bytebuffer拷贝测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferCopySpeed(256*1024*1024);
|
||||
}
|
||||
System.out.println("Directbytebuffer分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testDirectByteBufferAllocateSpeed(65536);
|
||||
}
|
||||
System.out.println("Bytebuffer分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferAllocateSpeed(65536);
|
||||
}
|
||||
System.out.println("BytebufferAllocator分配测试");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MemcpyBenchmark.testByteBufferAllocatorSpeed(65536);
|
||||
}
|
||||
break;
|
||||
//case "$$SYSTEM:":
|
||||
//System.out.println();
|
||||
//break;
|
||||
case "nodebenchmark":
|
||||
int nodenumber=100;
|
||||
if(sc.length>=2) {
|
||||
nodenumber=Integer.parseInt(sc[1]);
|
||||
}
|
||||
NodeBenchmark nbc=new NodeBenchmark(kpcje.getKlalbController(),nodenumber);
|
||||
nbc.startPerfing();
|
||||
break;
|
||||
default:
|
||||
System.out.println("未知命令,请输入help以查询命令说明");
|
||||
}
|
||||
|
||||
@@ -4,19 +4,29 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Inet6Address;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public class KLALBOutputStream extends DataOutputStream {
|
||||
|
||||
private WritableByteChannel channel;
|
||||
public KLALBOutputStream(OutputStream out) throws IOException {
|
||||
super(out);
|
||||
this.channel=Channels.newChannel(out);
|
||||
byte[]b=new byte[] {'K','L','A','L','B'};
|
||||
write(b);
|
||||
writeInt(CONST.bversion);
|
||||
writeInt(CONST.sversion);
|
||||
flush();
|
||||
}
|
||||
public void writePacket(KLALBPacket klb) throws IOException {
|
||||
public void writeKLALBPacket(KLALBPacket klb) throws IOException {
|
||||
writeInt((int) klb.getLength());
|
||||
KLALBPacket.writeKLALBPacketToStream(this, klb);
|
||||
}
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
writeInt( kp.limit());
|
||||
channel.write(kp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@@ -15,6 +16,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.perf.TEST1Packet;
|
||||
import org.kne.cloud.network.perf.TESTNPacket;
|
||||
|
||||
public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
public static final int KLALB_PROTOCOL_NUMBER=254;
|
||||
@@ -32,12 +35,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
public static final int VADDR=8;
|
||||
public static final int ADDLINES=9;
|
||||
public static final int NACKT=10;
|
||||
public static final int TEST=11;
|
||||
public static final int TESTN=11;
|
||||
public static final int VADDRACK=12;
|
||||
public static final int VADDRREQ=13;
|
||||
public static final int IPV6OVERKLALB=14;
|
||||
public static final int ADDR=15;
|
||||
public static final int ADDRREQ=16;
|
||||
public static final int TEST1=17;
|
||||
|
||||
//private static final int HEADER_CAPACITY = 32;
|
||||
|
||||
@@ -45,7 +49,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
//public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
|
||||
|
||||
protected volatile ByteBuffer klalbHeader;
|
||||
protected ByteBuffer klalbHeader;
|
||||
|
||||
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
|
||||
super(KLALB_PROTOCOL_NUMBER,false);
|
||||
@@ -55,7 +59,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
public KLALBPacket(int type,int headerLength) {
|
||||
super(KLALB_PROTOCOL_NUMBER,false);
|
||||
klalbHeader=ByteBuffer.allocate(headerLength);
|
||||
klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
|
||||
klalbHeader.put((byte) type);
|
||||
this.headerLength=headerLength;
|
||||
}
|
||||
@@ -83,7 +87,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return joinqueuetime;
|
||||
}
|
||||
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
sndtime=System.nanoTime();
|
||||
dto.write(klalbHeader.slice(0, headerLength));
|
||||
}
|
||||
@@ -93,7 +97,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
klalbHeader.limit(headerLength);
|
||||
while(klalbHeader.hasRemaining()){
|
||||
if(din.read(klalbHeader)==-1) {
|
||||
@@ -135,13 +139,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return klalbHeader;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/* ByteBuffer datax=klalbHeader;
|
||||
klalbHeader=null;
|
||||
if(datax!=null)
|
||||
KLALBPacket.databufferpool_40.back(datax);*/
|
||||
}
|
||||
|
||||
public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
||||
return readKLALBPacketFromChannel(Channels.newChannel(in));
|
||||
@@ -149,14 +146,14 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
|
||||
public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
|
||||
while(true) {
|
||||
ByteBuffer bb=databufferpool_40.borrow();
|
||||
ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
|
||||
bb.limit(1);
|
||||
while(bb.hasRemaining()){
|
||||
if(in.read(bb)==-1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
int type=bb.get(0);
|
||||
int type=bb.get(0)&0xff;
|
||||
bb.limit(bb.capacity());
|
||||
|
||||
KLALBPacket klp;
|
||||
@@ -196,8 +193,8 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
klp=new NACKTPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case TEST:
|
||||
klp=new TESTPacket(bb);
|
||||
case TESTN:
|
||||
klp=new TESTNPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case VADDRACK:
|
||||
@@ -220,9 +217,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
klp=new ADDRREQPacket(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
case TEST1:
|
||||
klp=new TEST1Packet(bb);
|
||||
klp.readFromChannel(in);
|
||||
return klp;
|
||||
}
|
||||
//throw new StreamCorruptedException("unknown package type:"+type);
|
||||
System.err.println("ignore unknown KLALBPacket type:"+type);
|
||||
throw new StreamCorruptedException("unknown package type:"+type);
|
||||
//System.err.println("ignore unknown KLALBPacket type:"+type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,10 +238,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void doDisposeAfterSend() {
|
||||
if(isDisposeAfterSend())
|
||||
dispose();
|
||||
}
|
||||
|
||||
private boolean ce=false;
|
||||
public void setCE(boolean ce) {
|
||||
this.ce=ce;
|
||||
|
||||
@@ -2,13 +2,26 @@ package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
public interface KLALBPacketLink {
|
||||
public void writePacket(KLALBPacket kp) throws IOException;
|
||||
public void setOutputTrafficCounters(AtomicLong[] al);
|
||||
public void setOutputPacketsCounters(AtomicLong[] al);
|
||||
public void setInputTrafficCounters(AtomicLong[] al);
|
||||
public void setInputPacketsCounters(AtomicLong[] al);
|
||||
public void writePacket(ByteBuffer kp) throws IOException;
|
||||
public default void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
|
||||
for (int i = 0; i < len; i++) {
|
||||
writePacket(kpp[off+i]);
|
||||
}
|
||||
}
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException;
|
||||
public void flush() throws IOException;
|
||||
public KLALBPacket readPacket()throws IOException;
|
||||
public KLALBPacket readKLALBPacket()throws IOException;
|
||||
public ByteBuffer readPacket()throws IOException;
|
||||
public void close() throws IOException;
|
||||
public boolean isClosed();
|
||||
public void setSoTimeout(int val) throws SocketException;
|
||||
|
||||
@@ -11,11 +11,13 @@ import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -112,15 +114,43 @@ public class KLALBProxySystem {
|
||||
case "KLALBController":
|
||||
JsonElement vase= entry.get("VirtualAddress");
|
||||
//System.out.println(vase);
|
||||
List<InetAddress>daddr=new ArrayList<InetAddress>();
|
||||
JsonElement vdns= entry.get("DNS");
|
||||
if(vdns!=null) {
|
||||
if(vdns instanceof JsonArray) {
|
||||
JsonArray arr=(JsonArray) vdns;
|
||||
for(JsonElement str:arr) {
|
||||
try {
|
||||
daddr.add((Inet6Address) InetAddress.getByName(str.getAsString()));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}else {
|
||||
try {
|
||||
daddr.add((Inet6Address) InetAddress.getByName(vdns.getAsString()));
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(vase!=null) {
|
||||
try {
|
||||
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()));
|
||||
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()),daddr);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else {
|
||||
klalbController=new KLALBController();
|
||||
klalbController=new KLALBController(daddr);
|
||||
}
|
||||
|
||||
|
||||
JsonElement vasn= entry.get("VirtualASN");
|
||||
if(vasn!=null) {
|
||||
klalbController.getIpv6Router().setASN (Long.parseLong( vasn.getAsString()));
|
||||
}
|
||||
|
||||
|
||||
JsonElement vsne=entry.get("VirtualSocketName");
|
||||
//if(vsne!=null) {
|
||||
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
|
||||
@@ -280,7 +310,7 @@ public class KLALBProxySystem {
|
||||
if(string.startsWith("SocketBridge")) {
|
||||
return new DefaultSocketBridgeFactory();
|
||||
}else if(string.startsWith("MinecraftSocketBridge")) {
|
||||
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf(), Integer.parseInt(string.substring(21)));
|
||||
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf().getAddress(), Integer.parseInt(string.substring(21)));
|
||||
}
|
||||
throw new IllegalArgumentException("unknown SocketBridge type:"+string);
|
||||
}
|
||||
|
||||
@@ -5,42 +5,69 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.UnresolvedAddressException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.kne.cloud.clock.AdjustedNanoClock;
|
||||
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6EmptyPayload;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.ipv6.RouteItem;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.NanoTimeSeries;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
import org.kne.cloud.network.perf.TESTNPacket;
|
||||
import org.kne.cloud.network.srv6.ACKSEQSSegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
|
||||
import org.kne.cloud.network.srv6.SEQSSegmentRoutingTLV;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
import org.kne.cloud.network.te.LoadingBalanceEntry;
|
||||
import org.kne.concurrent.DisruptorExecutor;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> ,LoadingBalanceEntry<KLALBRemoteLine>{
|
||||
|
||||
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> {
|
||||
|
||||
private static final int HEADER_CALIBRATE = 40;
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
private static final boolean showpacket = false;
|
||||
@@ -221,10 +248,19 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
|
||||
private static long MIN_SPEED=256*1024L;
|
||||
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,10000000L);
|
||||
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,20*1000000L);//50*1000000L
|
||||
private long congressSpeed = 0;
|
||||
private double loadPercent = 1.01;
|
||||
private double burstPercent = 1.3;//10.0
|
||||
private double windowPercent = 2;
|
||||
|
||||
private long MIN_RTTVAR=25000000L;
|
||||
|
||||
|
||||
private AtomicBoolean firstUpdate=new AtomicBoolean(true);
|
||||
private volatile long RTTMin=1000000000L;
|
||||
private volatile long RTTVar=1000000000L;
|
||||
private volatile long RTTAvg=1000000000L;
|
||||
private volatile long RTO=1000000000L;
|
||||
protected void startIO() {
|
||||
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
|
||||
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
|
||||
@@ -251,87 +287,153 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
addressGroup=new Inet6AddressGroup(i6a, 112);
|
||||
}
|
||||
} else {
|
||||
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress);
|
||||
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress,false);
|
||||
}
|
||||
//startRecord();
|
||||
|
||||
if (klalbController != null) {
|
||||
|
||||
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL(),klalbController.getLinkMonitor().getInTrafficAL()});
|
||||
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL(),klalbController.getLinkMonitor().getOutTrafficAL()});
|
||||
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL(),klalbController.getLinkMonitor().getInPacketCounterAL()});
|
||||
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL(),klalbController.getLinkMonitor().getOutPacketCounterAL()});
|
||||
} else {
|
||||
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL()});
|
||||
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL()});
|
||||
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL()});
|
||||
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL()});
|
||||
}
|
||||
kplink.setSoTimeout(20000);
|
||||
if(kplink.isStream()) {
|
||||
windowPercent=1.4;
|
||||
MIN_RTTVAR=50000000;
|
||||
burstPercent=2.0;//1.5
|
||||
//ackInterval=10000000L;
|
||||
}else {
|
||||
windowPercent=1.2;
|
||||
MIN_RTTVAR=20000000;
|
||||
burstPercent=2.0;
|
||||
//ackInterval=1000000L;
|
||||
}
|
||||
Thread timer = ThreadTool.makeVDaemonThread("重路由计时器线程", () -> {
|
||||
Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
|
||||
while((!kplink.isClosed()) && (!closed)) {
|
||||
|
||||
Collection<SendItem>vals= sendMap.values();
|
||||
for (Iterator<SendItem> iterator = vals.iterator(); iterator.hasNext();) {
|
||||
SendItem sitm = (SendItem) iterator.next();
|
||||
if(System.nanoTime() -sitm.getSendtime()>RTO) {
|
||||
iterator.remove();
|
||||
sendmapWindowUsed.addAndGet((int) -(sitm.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
//if(!kplink.isStream())
|
||||
if(sitm.getPacket().isPromise()) {
|
||||
IPv6Packet pktr=sitm.getPacket();
|
||||
pktr.setPriority(pktr.getPriority()-1);
|
||||
rerouteConsumer.accept(pktr);
|
||||
}
|
||||
//System.out.println("reroute");
|
||||
}
|
||||
}
|
||||
for (Iterator<Entry<UUID, Long>> iterator = recvedUIDMap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<UUID, Long> sendItem = (Entry<UUID, Long>) iterator.next();
|
||||
if(System.nanoTime()-sendItem.getValue()>10000000000L) {
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
}
|
||||
if(checkACKTime()) {
|
||||
sendALLIPv6ACK();
|
||||
//System.out.println("ACK发送");
|
||||
}
|
||||
try {
|
||||
Thread.sleep(4);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
|
||||
Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
|
||||
tlock = Thread.currentThread();
|
||||
//tlock.setPriority(Thread.NORM_PRIORITY+1);
|
||||
try {
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
if(addressGroup!=null) {
|
||||
writePacketToKPL(new ADDRPacket(addressGroup));
|
||||
writePacketToKPL(new ADDRPacket(addressGroup));
|
||||
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
|
||||
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
|
||||
}
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
|
||||
flushKPL();
|
||||
KLALBPacket kpp = null;
|
||||
ByteBuffer[] kpp = null;
|
||||
int kppslen=0;
|
||||
while ((!kplink.isClosed()) && (!closed)) {
|
||||
// TimeDebugger tdb=new TimeDebugger();
|
||||
// tdb.putTime("start");
|
||||
if(checkBandwidthReportTime()) {
|
||||
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
|
||||
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg(), monitor.getInSpeedAvg()));
|
||||
}
|
||||
if (checkPingTimeSleep()) {
|
||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
if (remoteVaddr == null)
|
||||
writePacketToKPL(new VADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new VADDRREQPacket());
|
||||
if(peerAddress==null)
|
||||
writePacketToKPL(new ADDRREQPacket());
|
||||
writeKLALBPacketToKPL(new ADDRREQPacket());
|
||||
|
||||
}else {
|
||||
KLALBPacket kpip = IsendDequeList.poll();
|
||||
if (kpip != null) {
|
||||
writePacketToKPL(kpip);
|
||||
writeKLALBPacketToKPL(kpip);
|
||||
|
||||
}else {
|
||||
|
||||
// tdb.putTime("Isend");
|
||||
|
||||
if (kpp == null) {
|
||||
do {
|
||||
kpp = sendDequeList.poll();
|
||||
} while (kpp != null && kpp.isDisposed());
|
||||
if(kpp==null) {
|
||||
ByteBuffer tkpp = sendDequeList.poll();
|
||||
if(tkpp==null) {
|
||||
monitor.setQueueingDelay(0);
|
||||
}else {
|
||||
kpp=new ByteBuffer[10];
|
||||
kpp[0]=tkpp;
|
||||
int i=1;
|
||||
for(;i<kpp.length;i++) {
|
||||
ByteBuffer xkpp=sendDequeList.poll();
|
||||
if(xkpp==null)
|
||||
break;
|
||||
kpp[i]=xkpp;
|
||||
}
|
||||
kppslen=i;
|
||||
}
|
||||
}
|
||||
// System.out.println(sendDequeList.size());
|
||||
if (kpp != null) {
|
||||
// TimeDebugger tdb=new TimeDebugger();
|
||||
//tdb.putTime("start");
|
||||
KLALBPacket kppt=kpp;
|
||||
kppt.lockAll();
|
||||
try {
|
||||
if (kpp.isSomeDisposed()) {
|
||||
kpp = null;
|
||||
} else {
|
||||
|
||||
|
||||
// if (congress.checkTransmit(length)) {
|
||||
|
||||
writePacketToKPL(kpp);
|
||||
kplink.writePackets(kpp,0,kppslen);
|
||||
if (checkPingTime()) {
|
||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
}
|
||||
monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
|
||||
//monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
|
||||
/*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) {
|
||||
resetSleepTimer();
|
||||
}*/
|
||||
kpp.doDisposeAfterSend();
|
||||
kpp = null;
|
||||
}
|
||||
|
||||
//}
|
||||
} finally {
|
||||
kppt.unlockAll();
|
||||
}
|
||||
|
||||
//tdb.putTime("sendToLink");
|
||||
//tdb.print();
|
||||
}else {
|
||||
LockSupport.parkNanos(1000000);
|
||||
LockSupport.parkNanos(10000000L);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,6 +460,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
// System.out.println(sendDequeList.isEmpty());
|
||||
Thread.yield();
|
||||
}
|
||||
}catch(StreamCorruptedException sce) {
|
||||
sce.printStackTrace();
|
||||
} catch (IOException | UnresolvedAddressException e) {
|
||||
if (debug)
|
||||
e.printStackTrace();
|
||||
@@ -370,28 +474,26 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
boolean fst = true;
|
||||
AtomicBoolean fst = new AtomicBoolean(true);
|
||||
long stime = 5000000000L;
|
||||
while ((!kplink.isClosed()) && (!closed)) {
|
||||
long readStart = System.nanoTime();
|
||||
KLALBPacket kpp = readPacketFromKPL();
|
||||
/*long readTime = System.nanoTime() - readStart;
|
||||
readTime *= 10;
|
||||
if (readTime > stime) {
|
||||
stime = readTime;
|
||||
} else {
|
||||
stime = (stime * 999 + readTime) / 1000;
|
||||
}
|
||||
if (stime < 2000000000L) {
|
||||
stime = 2000000000L;
|
||||
}*/
|
||||
|
||||
// System.out.println(readTime);
|
||||
ByteBuffer kppb = kplink.readPacket();
|
||||
|
||||
kplink.setSoTimeout(3000);
|
||||
kplink.setSoTimeout((int) (stime / 1000000));
|
||||
if (kpp == null) {
|
||||
if (kppb == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
KLALBPacket kpp=null;
|
||||
try {
|
||||
kpp = KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(kppb));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(kpp==null)
|
||||
return;
|
||||
debugShowPacket("RX",kpp);
|
||||
switch (kpp.getType()) {
|
||||
case KLALBPacket.PING:
|
||||
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
|
||||
@@ -404,29 +506,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
|
||||
long DsndDelayFactor;
|
||||
long DrcvDelayFactor;
|
||||
|
||||
adjnc.getLock().lock();
|
||||
|
||||
AdjustedNanoClock adjc=adjnc;
|
||||
adjc.getLock().lock();
|
||||
try {
|
||||
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
if (DsndDelayFactor < 0) {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
|
||||
} else {
|
||||
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.setDelta(adjc.getDelta() + DsndDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
}
|
||||
} else {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
adjc.setDelta(adjc.getDelta() - DrcvDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
adjnc.getLock().unlock();
|
||||
adjc.getLock().unlock();
|
||||
}
|
||||
|
||||
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
|
||||
@@ -436,7 +539,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
//pingInterval = monitor.getLatencyAvg()+2000000L;
|
||||
|
||||
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
|
||||
loadPercent =Math.max( 1.2,0.4);
|
||||
//loadPercent =Math.max( 1.3,0.4);
|
||||
}
|
||||
|
||||
LockSupport.unpark(tlock);
|
||||
@@ -446,9 +549,12 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if (bwi.getDownSpeed() >= congressSpeed) {
|
||||
congressSpeed = bwi.getDownSpeed();
|
||||
} else {
|
||||
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
|
||||
congressSpeed = (congressSpeed * 199 + bwi.getDownSpeed()) / 200;
|
||||
}
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
|
||||
bandwidthDistributer.setTotalBandwidth (congressSpeed );
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * burstPercent)) );
|
||||
//reallimit=(int) (congress.getLimitspeed()*monitor.getLatencyMin()/1000000000L);
|
||||
reallimit=(int) (Math.max(MIN_SPEED,(long) (congressSpeed*windowPercent ))*Math.max(2000000L,RTTMin)/1000000000L);
|
||||
// System.out.println(congressSpeed);
|
||||
break;
|
||||
case KLALBPacket.ADDRREQ:
|
||||
@@ -460,7 +566,13 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if(addressGroup==null) {
|
||||
byte[]ab=peerAddress.getAddress().getAddress();
|
||||
ab[15]=2;
|
||||
Inet6AddressGroup ardg2=new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
|
||||
Inet6AddressGroup ardg2=null;
|
||||
try {
|
||||
ardg2 = new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(ardg2!=null)
|
||||
addressGroup=ardg2;
|
||||
}
|
||||
break;
|
||||
@@ -475,39 +587,124 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
if (klalbController != null) {
|
||||
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
|
||||
}
|
||||
if (fst) {
|
||||
if (fst.compareAndSet(true, false)) {
|
||||
// coll.resetCoolingTime();
|
||||
monitor.setState(MonitorData.ONLINE);
|
||||
fst = false;
|
||||
}
|
||||
break;
|
||||
case KLALBPacket.VADDRACK:
|
||||
break;
|
||||
case KLALBPacket.TEST:
|
||||
case KLALBPacket.TESTN:
|
||||
break;
|
||||
case KLALBPacket.IPV6OVERKLALB:
|
||||
if(ipv6con!=null) {
|
||||
|
||||
IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp;
|
||||
IPv6Packet iv6= ivk.getIPv6Packet();
|
||||
ivk.putTimePassport("unpacked");
|
||||
ivk.printPassport();
|
||||
iv6.putTimePassport("unpackFromLink");
|
||||
|
||||
IPSequence val=null;
|
||||
IPv6SegmentRoutingHeader srh= iv6.getSRHHeader();
|
||||
if(srh!=null) {
|
||||
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
|
||||
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
IPv6SegmentRoutingTLV tlv=l.get(i);
|
||||
if(tlv instanceof SEQSSegmentRoutingTLV) {
|
||||
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
|
||||
// if(seqs.isPromise()) {
|
||||
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
|
||||
//}
|
||||
|
||||
}else if(tlv instanceof ACKSEQSSegmentRoutingTLV) {
|
||||
ACKSEQSSegmentRoutingTLV aseq=(ACKSEQSSegmentRoutingTLV) tlv;
|
||||
l.remove(i);
|
||||
i--;
|
||||
|
||||
SendItem ipv6;
|
||||
if((ipv6=sendMap.remove(aseq.getIPSequence()))!=null) {
|
||||
sendmapWindowUsed.addAndGet((int) -(ipv6.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
long RTTC=System.nanoTime()-ipv6.getSendtime();
|
||||
if(RTTC<=RTTMin) {
|
||||
RTTMin=RTTC;
|
||||
}else {
|
||||
RTTMin= (RTTMin*99999+RTTC)/100000;
|
||||
}
|
||||
if(firstUpdate.compareAndSet(true, false)) {
|
||||
RTTAvg=RTTC;
|
||||
RTTVar=RTTC/2;
|
||||
|
||||
}else {
|
||||
RTTVar=(RTTVar*3+Math.abs(RTTAvg-RTTC))/4;
|
||||
RTTAvg= (RTTAvg*7+RTTC)/8;
|
||||
}
|
||||
RTO=RTTAvg+Math.max(MIN_RTTVAR, RTTVar*4);//RTTVar*4
|
||||
//System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size());
|
||||
}else {
|
||||
// System.out.println("miss:"+aseq.getSequence()+" "+sendMap.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(val!=null)
|
||||
ackIDs.add(val);
|
||||
/*if(val!=null&&peerAddress!=null) {
|
||||
UUID val2=val;
|
||||
HighPerformanceExecutor.defaultExecutor.execute(()->{
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(addressGroup.getAddress());
|
||||
ipv.setDestinationAddress(peerAddress.getAddress());
|
||||
ipv.setPriority(0);
|
||||
ipv.enableECN();
|
||||
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
|
||||
srh2.getAddresses().add(peerAddress.getAddress());
|
||||
|
||||
srh2.getTlvs().add(new ACKSEQSSegmentRoutingTLV(val2,true));
|
||||
|
||||
ipv.getHeaders().add(srh2);
|
||||
ipv.setPayload(new IPv6EmptyPayload());
|
||||
|
||||
sendIPacket(new IPv6OverKLALBPacket( ipv));
|
||||
//System.out.println("ack:"+val);
|
||||
});
|
||||
}*/
|
||||
|
||||
if(ipv6con!=null) {
|
||||
if(iv6.getPayload()instanceof IPv6EmptyPayload) {
|
||||
//iv6.dispose();
|
||||
}else {
|
||||
if(val!=null) {
|
||||
Long l=recvedUIDMap.putIfAbsent(val.getUuid(), System.nanoTime());
|
||||
if(l==null) {
|
||||
ipv6con.accept(iv6);
|
||||
}else {
|
||||
//System.out.println("虚假重传:"+val.getUuid());
|
||||
}
|
||||
}else {
|
||||
ipv6con.accept(iv6);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while (rec == null) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
if(rec!=null)
|
||||
rec.accept( kpp);
|
||||
break;
|
||||
}
|
||||
});
|
||||
Thread.yield();
|
||||
}
|
||||
}catch(StreamCorruptedException sce) {
|
||||
sce.printStackTrace();
|
||||
} catch (IOException | UnresolvedAddressException e) {
|
||||
if (debug)
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
}catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
monitor.setState(MonitorData.OFFLINE);
|
||||
@@ -518,17 +715,14 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/*KLALBPacket pack;
|
||||
while((pack=sendDequeList.poll())!=null) {
|
||||
try {
|
||||
if(remoteVaddr!=null) {
|
||||
klalbController.sendPacketToLinkAddress(remoteVaddr, pack);
|
||||
if(debug)
|
||||
System.out.println("RETRY:"+pack);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Collection<SendItem>vals= sendMap.values();
|
||||
SendItem[]packs= vals.toArray(new SendItem[0]);
|
||||
for (SendItem iPv6Packet : packs) {
|
||||
rerouteConsumer.accept(iPv6Packet.getPacket());
|
||||
//System.out.println("重路由:"+iPv6Packet);
|
||||
}
|
||||
}*/
|
||||
sendMap.clear();
|
||||
sendmapWindowUsed.set(0);
|
||||
}
|
||||
|
||||
if (closed) {
|
||||
@@ -544,63 +738,98 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}).start();
|
||||
|
||||
}
|
||||
private ConcurrentLinkedQueue<IPSequence> ackIDs=new ConcurrentLinkedQueue<>();
|
||||
private volatile long prevAckTime=System.nanoTime();
|
||||
private volatile long ackInterval=1000000L;
|
||||
private boolean checkACKTime() {
|
||||
long cu = System.nanoTime();
|
||||
if (cu - prevAckTime > ackInterval) {
|
||||
prevAckTime = cu;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private void sendALLIPv6ACK() {
|
||||
if(peerAddress!=null) {
|
||||
while(true) {
|
||||
int rez=sendIPv6ACK();
|
||||
if(rez<=0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private int sendIPv6ACK() {
|
||||
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
|
||||
int adds=addACKSEQToSRH(srh2,40);
|
||||
if(adds<=0)
|
||||
return adds;
|
||||
|
||||
//System.out.println(adds+"ACKS");
|
||||
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(addressGroup.getAddress());
|
||||
ipv.setDestinationAddress(peerAddress.getAddress());
|
||||
ipv.setPriority(0);
|
||||
ipv.enableECN();
|
||||
srh2.getAddresses().add(peerAddress.getAddress());
|
||||
|
||||
|
||||
ipv.getHeaders().add(srh2);
|
||||
ipv.setPayload(new IPv6EmptyPayload());
|
||||
|
||||
sendIPacket(new IPv6OverKLALBPacket( ipv));
|
||||
//System.out.println("ack:"+val);
|
||||
return adds;
|
||||
}
|
||||
|
||||
private int addACKSEQToSRH(IPv6SegmentRoutingHeader srh,int maxAckCount){
|
||||
int i = 0;
|
||||
for (; i < maxAckCount; i++) {
|
||||
|
||||
IPSequence ackid= ackIDs.poll();
|
||||
if(ackid!=null) {
|
||||
srh.getTlvs().add(new ACKSEQSSegmentRoutingTLV(ackid, ackid.isPromise()));
|
||||
}else {
|
||||
prevAckTime=System.nanoTime();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private void flushKPL() throws IOException {
|
||||
kplink.flush();
|
||||
}
|
||||
|
||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = kplink.readPacket();
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.out.println("RX:" + packet);
|
||||
}
|
||||
private KLALBPacket readKLALBPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = kplink.readKLALBPacket();
|
||||
debugShowPacket("RX",packet);
|
||||
if (packet != null) {
|
||||
packet.putTimePassport("received");
|
||||
long length=packet.getLength();
|
||||
monitor.getInTrafficAL().addAndGet(length);
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getInTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getInPacketCounterAL().incrementAndGet();
|
||||
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
||||
long length=packet.getLength();
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
|
||||
kplink.writePacket(packet);
|
||||
private void writeKLALBPacketToKPL(KLALBPacket packet) throws IOException {
|
||||
kplink.writeKLALBPacket(packet);
|
||||
packet.putTimePassport("sended");
|
||||
packet.printPassport();
|
||||
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.err.println("TX:" + packet);
|
||||
}
|
||||
debugShowPacket("TX",packet);
|
||||
}
|
||||
|
||||
private void writePacketToKPL(KLALBPacket packet,long length) throws IOException {
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
if (klalbController != null)
|
||||
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
|
||||
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
|
||||
kplink.writePacket(packet);
|
||||
|
||||
private void debugShowPacket(String label, KLALBPacket packet) {
|
||||
if (showpacket) {
|
||||
if (!(packet instanceof PINGPacket))
|
||||
if (!(packet instanceof PONGPacket))
|
||||
if (!(packet instanceof BWINFPacket))
|
||||
System.err.println("TX:" + packet);
|
||||
System.err.println(label+":" + packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +851,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private volatile long time = System.nanoTime();
|
||||
private volatile long pingInterval = 10000000L;
|
||||
private volatile long pingIntervalSleep = 200000000L;
|
||||
private volatile long pingIntervalSleep = 500000000L;
|
||||
|
||||
private boolean checkPingTime() {
|
||||
long cu = System.nanoTime();
|
||||
@@ -649,7 +878,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private volatile long bwtime = System.nanoTime();
|
||||
private volatile long bwpingInterval = 10000000L;
|
||||
private volatile long bwpingIntervalSleep = 100000000L;
|
||||
private volatile long bwpingIntervalSleep = 200000000L;
|
||||
private boolean checkBandwidthReportTime(){
|
||||
long cu = System.nanoTime();
|
||||
if (cu - bwtime > bwpingIntervalSleep) {
|
||||
@@ -667,16 +896,25 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
|
||||
|
||||
private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
|
||||
private PriorityBlockingQueue<ByteBuffer> sendDequeList = new PriorityBlockingQueue<ByteBuffer>();
|
||||
|
||||
public PriorityBlockingQueue<KLALBPacket> getQueue() {
|
||||
public PriorityBlockingQueue<ByteBuffer> getQueue() {
|
||||
return sendDequeList;
|
||||
}
|
||||
|
||||
protected void sendPacket(KLALBPacket blk) {
|
||||
debugShowPacket("TX",blk);
|
||||
blk.markJoinqueuetime();
|
||||
sendDequeList.add(blk);
|
||||
ByteBuffer buf=NetworkPacket.bufferAllocator.allocate((int) blk.getLength());
|
||||
try {
|
||||
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel(buf), blk);
|
||||
buf.flip();
|
||||
sendDequeList.add(buf);
|
||||
LockSupport.unpark(tlock);
|
||||
} catch (IOException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendIPacket(KLALBPacket blk) {
|
||||
@@ -688,21 +926,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
this.rec = rec;
|
||||
}
|
||||
|
||||
/*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
|
||||
sendDequeList.remove(klalbPacket);
|
||||
}*/
|
||||
|
||||
public long statLengthBefore(long l) {
|
||||
AtomicLong al = new AtomicLong();
|
||||
for (Iterator<KLALBPacket> iterator = sendDequeList.iterator(); iterator.hasNext();) {
|
||||
KLALBPacket queue = iterator.next();
|
||||
if (queue.getPriority() <= l) {
|
||||
al.addAndGet(queue.getLength());
|
||||
}
|
||||
|
||||
}
|
||||
return al.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private volatile long predictTime;
|
||||
|
||||
@@ -744,7 +969,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
}
|
||||
|
||||
private static final TESTPacket testPacket = new TESTPacket(60000);
|
||||
private static final TESTNPacket testPacket = new TESTNPacket(60000);
|
||||
private volatile boolean pressure = false;
|
||||
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
|
||||
|
||||
@@ -774,46 +999,21 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
return predictTime;
|
||||
}
|
||||
|
||||
private List<Double>ranks=new ArrayList<Double>();
|
||||
|
||||
private Consumer<IPv6Packet> ipv6con;
|
||||
@Override
|
||||
public void noticeRank(int rank) {
|
||||
while(rank>=ranks.size()) {
|
||||
ranks.add(0.5);
|
||||
}
|
||||
for (int i = 0; i < ranks.size(); i++) {
|
||||
if(i==rank) {
|
||||
ranks.set(i, (ranks.get(i)*99.0+1.0D)/100.0);
|
||||
}else {
|
||||
ranks.set(i, ranks.get(i)*99.0/100.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWeightAtRank(int rank) {
|
||||
while(rank>=ranks.size()) {
|
||||
ranks.add(0.5);
|
||||
}
|
||||
return ranks.get(rank);
|
||||
}
|
||||
|
||||
public List<Double> getRanks() {
|
||||
|
||||
return ranks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoopBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private BandwidthDistributer<Inet6Address> bandwidthDistributer=new BandwidthDistributer<Inet6Address>();
|
||||
|
||||
@Override
|
||||
public List<Neighbor> getNeighborsInfo() {
|
||||
List<Neighbor>hs=new ArrayList<>();
|
||||
if(peerAddress!=null) {
|
||||
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor));
|
||||
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor,bandwidthDistributer));
|
||||
//System.out.println(peerAddress+" "+addressGroup);
|
||||
}
|
||||
return hs;
|
||||
@@ -821,26 +1021,77 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
|
||||
|
||||
|
||||
private Map<IPSequence,SendItem> sendMap= new ConcurrentHashMap<>();
|
||||
private AtomicInteger sendmapWindowUsed=new AtomicInteger(0);
|
||||
private Map<UUID,Long>recvedUIDMap=new ConcurrentHashMap<UUID, Long>();
|
||||
|
||||
private volatile int inputchachesize = 8192 * 4000;
|
||||
private volatile int outputchachesize = 8192 * 240;//500
|
||||
private volatile int reallimit = 65536 ;
|
||||
|
||||
private Consumer<IPv6Packet> rerouteConsumer;
|
||||
|
||||
@Override
|
||||
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException {
|
||||
pack.lockAll();
|
||||
try {
|
||||
if(pack.isSomeDisposed()) {
|
||||
return;
|
||||
//只有已连接的链路才能传输数据
|
||||
if(monitor.getState()==MonitorData.ONLINE) {
|
||||
|
||||
//if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
|
||||
|
||||
//获得数据包的SRv6扩展头部
|
||||
IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
|
||||
|
||||
IPSequence val=null;
|
||||
if(srh!=null) {
|
||||
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
IPv6SegmentRoutingTLV tlv=l.get(i);
|
||||
if(tlv instanceof SEQSSegmentRoutingTLV) {
|
||||
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
|
||||
//if(seqs.isPromise())
|
||||
//获得数据包的序号
|
||||
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(val!=null) {
|
||||
//放入滑动窗口中并记录缓冲区大小占用
|
||||
SendItem old= sendMap.put(val,new SendItem( pack));
|
||||
if(old!=null) {
|
||||
sendmapWindowUsed.addAndGet((int) -(old.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
|
||||
}
|
||||
sendmapWindowUsed.addAndGet((int) (pack.getPayload().getLength()+HEADER_CALIBRATE));
|
||||
//System.out.println("add: "+ val+" "+sendMap.size());
|
||||
}
|
||||
}
|
||||
//捎带发送反方向的ACK给对方发送过来的数据包,减小设备性能开销
|
||||
if(srh!=null) {
|
||||
addACKSEQToSRH(srh,10);
|
||||
}
|
||||
//发送数据包
|
||||
sendIPv6PacketToLink(pack);
|
||||
//}
|
||||
|
||||
}else {
|
||||
if(rerouteConsumer!=null) {
|
||||
rerouteConsumer.accept(pack);
|
||||
}
|
||||
}
|
||||
if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
|
||||
this.rerouteConsumer=rerouteConsumer;
|
||||
}
|
||||
|
||||
private void sendIPv6PacketToLink(IPv6Packet pack) {
|
||||
IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack);
|
||||
kipv6.setPriority(pack.getPriority());
|
||||
kipv6.setDisposeAfterSend(true);
|
||||
pack.putTimePassport("packdInLink");
|
||||
pack.printPassport();
|
||||
sendPacketToLink(kipv6);
|
||||
}
|
||||
}finally {
|
||||
pack.unlockAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPacketToLink(KLALBPacket packet) {
|
||||
@@ -850,13 +1101,18 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCongress(IPv6Packet iPv6Packet) {
|
||||
int size=getQueue().size();
|
||||
if(size>30) {
|
||||
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
|
||||
if(monitor.getInDelay()>3000000000L||monitor.getOutDelay()>3000000000L||monitor.getInSpeedAvg()<=0||monitor.getOutSpeedAvg()<=0)
|
||||
return true;
|
||||
}else {
|
||||
return !congress.checkTransmit(iPv6Packet.getLength());
|
||||
}
|
||||
boolean congress=sendmapWindowUsed.get()>reallimit*scale;
|
||||
return congress;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
|
||||
boolean xcongress=!congress.checkTransmit(iPv6Packet.getLength());
|
||||
return xcongress;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -879,6 +1135,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
|
||||
this.ipv6con=ipv6con;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RouteItem> getRouteItems() {
|
||||
List<RouteItem> rlist=new ArrayList<>();
|
||||
|
||||
Inet6AddressGroup adg=addressGroup;
|
||||
if(adg!=null)
|
||||
rlist.add(new RouteItem(new Inet6AddressGroup(adg.getAddress(), 128),
|
||||
adg.getAddress(), this, "Direct", 0, 0, null, "D",true));
|
||||
|
||||
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
|
||||
.iterator(); iteratorx.hasNext();) {
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
|
||||
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ri);
|
||||
|
||||
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
|
||||
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
|
||||
rlist.add(ris);
|
||||
|
||||
}
|
||||
return rlist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
@@ -135,8 +137,28 @@ public class KLALBUtils {
|
||||
Color col=new Color( r,g,0);
|
||||
return col;
|
||||
}
|
||||
public static Color getColorByLoadPercentagex(float f) {
|
||||
int r=0;
|
||||
int g=200;
|
||||
if(f<50f) {
|
||||
r+=f/50f*200f;
|
||||
}else {
|
||||
r=200;
|
||||
g-=(f-50f)/50f*200f;
|
||||
}
|
||||
if(r>200)
|
||||
r=200;
|
||||
if(r<0)
|
||||
r=0;
|
||||
if(g>200)
|
||||
g=200;
|
||||
if(g<0)
|
||||
g=0;
|
||||
Color col=new Color( r,g,0);
|
||||
return col;
|
||||
}
|
||||
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress)
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress,boolean buffered)
|
||||
throws IOException {
|
||||
if (targetAddress.isStream()) {
|
||||
if (targetAddress.supportNIO()) {
|
||||
@@ -164,14 +186,23 @@ public class KLALBUtils {
|
||||
}
|
||||
}
|
||||
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress,
|
||||
MultipurposeSocketAddress targetAddress, int timeout) throws UnknownHostException, IOException {
|
||||
MultipurposeSocketAddress targetAddress,boolean buffered, int timeout) throws UnknownHostException, IOException {
|
||||
if (targetAddress.isStream()) {
|
||||
if (targetAddress.supportNIO()) {
|
||||
if (bindAddress != null) {
|
||||
if(buffered) {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress
|
||||
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
|
||||
}else {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress
|
||||
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
|
||||
}
|
||||
} else {
|
||||
if(buffered) {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
|
||||
}else {
|
||||
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bindAddress != null) {
|
||||
@@ -190,7 +221,116 @@ public class KLALBUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final String IPv6Reg = "([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$"
|
||||
+ "|^:((:[\\da-fA-F]{1,4}){1,6}|:)$"
|
||||
+ "|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$"
|
||||
+ "|^([\\da-fA-F]{1,4}:){6}:"; // IPv6地址的格式
|
||||
|
||||
/**
|
||||
* 将一个IPv6地址转为全写格式,全写中的前导0省略
|
||||
* 例:将1ade:03da:0::转为1ade:3da:0:0:0:0:0:0
|
||||
*
|
||||
* @param IPv6Str
|
||||
* @return fullIPv6
|
||||
*/
|
||||
public static String parseFullIPv6(String IPv6Str) {
|
||||
// 判断IPv6地址的格式是否正确
|
||||
if (!IPv6Str.matches(IPv6Reg)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String[] arr = new String[]{"0", "0", "0", "0", "0", "0", "0", "0"};
|
||||
|
||||
// 将IPv6地址用::分开
|
||||
// 如果IPv6地址为::,tempArr.length==0
|
||||
// 如果不包含::或以::结尾,tempArr.length==1
|
||||
// 如果以::开头或::在中间,tempArr.length==2
|
||||
String[] tempArr = IPv6Str.split("::");
|
||||
|
||||
// tempArr[0]用:分开,填充到arr前半部分
|
||||
if (tempArr.length > 0) {
|
||||
// new String[0]为空数组,因为"".split(":")为{""},如果tempArr[0]=="",此时数组包含一个元素
|
||||
String[] tempArr0 = tempArr[0].isEmpty() ? new String[0] : tempArr[0].split(":");
|
||||
for (int i = 0; i < tempArr0.length; i++) {
|
||||
// 如果是纯数字,用parseInt去除前导0,如果包含字母,用正则去除前导0
|
||||
arr[i] = tempArr0[i].matches("\\d+")
|
||||
? (Integer.parseInt(tempArr0[i]) + "")
|
||||
: tempArr0[i].replaceAll("^(0+)", "");
|
||||
}
|
||||
}
|
||||
|
||||
// tempArr[1]用:分开,填充到arr后半部分
|
||||
if (tempArr.length > 1) {
|
||||
String[] tempArr1 = tempArr[1].isEmpty() ? new String[0] : tempArr[1].split(":");
|
||||
for (int i = 0; i < tempArr1.length; i++) {
|
||||
arr[i + arr.length - tempArr1.length] = tempArr1[i].matches("\\d+")
|
||||
? (Integer.parseInt(tempArr1[i]) + "")
|
||||
: tempArr1[i].replaceAll("^(0+)", "");
|
||||
}
|
||||
}
|
||||
|
||||
return join(arr, ":");
|
||||
}
|
||||
|
||||
private static String join(String[] arr, String string) {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
sb.append(arr[i]);
|
||||
if(i+1<arr.length) {
|
||||
sb.append(string);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* 将一个IPv6地址转为简写格式
|
||||
* 例:将1ade:03da:0::转为1ade:3da::
|
||||
*
|
||||
* @param IPv6Str
|
||||
* @return AbbrIPv6
|
||||
*/
|
||||
public static String parseAbbrIPv6(String IPv6Str) {
|
||||
// 将一个IPv6地址转为全写格式,全写中的前导0省略
|
||||
String fullIPv6 = parseFullIPv6(IPv6Str);
|
||||
if (fullIPv6.isEmpty()) { // 如果IPv6地址的格式不正确
|
||||
return "";
|
||||
}
|
||||
|
||||
// 将1ade:3da:0:0:0:0:0:99转为{"-","-","0","0","0","0","0","-"}
|
||||
String[] arr = fullIPv6.split(":");
|
||||
for (int i = 0, len = arr.length; i < len; i++) {
|
||||
if (!"0".equals(arr[i])) {
|
||||
arr[i] = "-";
|
||||
}
|
||||
}
|
||||
|
||||
// 找到最长的连续的0
|
||||
Pattern pattern = Pattern.compile("0{2,}");
|
||||
Matcher matcher = pattern.matcher(join(arr, ""));
|
||||
String maxStr = "";
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
while (matcher.find()) {
|
||||
if (maxStr.length() < matcher.group().length()) {
|
||||
maxStr = matcher.group();
|
||||
start = matcher.start();
|
||||
end = matcher.end();
|
||||
}
|
||||
}
|
||||
|
||||
// 合并
|
||||
arr = fullIPv6.split(":");
|
||||
if (maxStr.length() > 0) {
|
||||
for (int i = start; i < end; i++) {
|
||||
arr[i] = ":";
|
||||
}
|
||||
}
|
||||
return join(arr, ":").replaceAll(":{2,}", "::");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.kne.cloud.network.RawSocket;
|
||||
import org.kne.cloud.network.RawSocketImpl;
|
||||
import org.kne.cloud.network.VirtualRawSocket;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
|
||||
public class KLALBVirtualRawSocket extends VirtualRawSocket {
|
||||
|
||||
public KLALBVirtualRawSocket(SRv6Router controller) {
|
||||
super(new KLALBVirtualRawSocketImpl(controller));
|
||||
}
|
||||
|
||||
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress) throws SocketException {
|
||||
super(new KLALBVirtualRawSocketImpl(controller),bindAddress);
|
||||
}
|
||||
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress,int bindProtocol) throws SocketException {
|
||||
super(new KLALBVirtualRawSocketImpl(controller),bindAddress,bindProtocol);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.BindException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.RawSocketImpl;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.VirtualRawSocketImpl;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
|
||||
import org.kne.cloud.network.srv6.PacketConsumer;
|
||||
import org.kne.cloud.network.srv6.SRv6Router;
|
||||
import org.kne.concurrent.HighPerformanceExecutor;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{
|
||||
|
||||
private boolean ipHeaderInclude=false;
|
||||
|
||||
private SRv6Router router;
|
||||
|
||||
|
||||
protected volatile Inet6Address remoteaddr;
|
||||
protected volatile Inet6Address localaddr;
|
||||
|
||||
private int bindProtocolNumber;
|
||||
|
||||
private volatile int inputchachesize = 1024*1024;
|
||||
|
||||
protected SRv6Router getRouter() {
|
||||
return router;
|
||||
}
|
||||
|
||||
public KLALBVirtualRawSocketImpl(SRv6Router router) {
|
||||
super();
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOption(int optID, Object value) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOption(int optID) throws SocketException {
|
||||
// TODO 自动生成的方法存根
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setIPHeaderInclude(boolean ipHeaderInclude) throws IOException {
|
||||
this.ipHeaderInclude=ipHeaderInclude;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getIPHeaderInclude() throws IOException {
|
||||
return ipHeaderInclude;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUseSelectTimeout(boolean useSelect) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getUseSelectTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSendTimeout(int timeout) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSendTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setReceiveTimeout(int timeout) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getReceiveTimeout() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
router.getProtocolNumberRegister().remove(bindProtocolNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bind(InetAddress address,int protocolNumber) throws SocketException{
|
||||
if(protocolNumber<0) {
|
||||
throw new UnsupportedOperationException("unsupprted bind all protocols");
|
||||
}
|
||||
try {
|
||||
if (address.equals(Inet4Address.getByName("0.0.0.0"))) {
|
||||
address = Inet6Address.getByName("::0");
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!(address instanceof Inet6Address)) {
|
||||
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
|
||||
}
|
||||
if ((!address.isAnyLocalAddress()) && (!address.equals(router.getLocator().getAddress()))) {
|
||||
throw new BindException("must bind to self");
|
||||
}
|
||||
|
||||
localaddr=(Inet6Address) address;
|
||||
this.bindProtocolNumber=protocolNumber;
|
||||
if(router.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) {
|
||||
throw new BindException("protocol number already bind");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void join(InetAddress inetaddr) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leave(InetAddress inetaddr) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void joinGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leaveGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void send(DatagramPacket p) throws IOException {
|
||||
ByteBuffer buf= ByteBuffer.wrap(p.getData(), p.getOffset(), p.getLength());
|
||||
if(ipHeaderInclude) {
|
||||
|
||||
}else {
|
||||
HighPerformanceExecutor.defaultExecutor.execute(() -> {
|
||||
IPv6Packet ipv=new IPv6Packet();
|
||||
ipv.setVersion(6);
|
||||
ipv.setTrafficClass(0);
|
||||
ipv.setFlowLabel(0);
|
||||
ipv.setHopLimit(255);
|
||||
ipv.setSourceAddress(router.getLocator().getAddress());
|
||||
InetAddress address= p.getAddress();
|
||||
if (!(address instanceof Inet6Address)) {
|
||||
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
|
||||
}
|
||||
ipv.setDestinationAddress((Inet6Address)address);
|
||||
ipv.setPriority(3);
|
||||
//ipv.enableECN();
|
||||
IPv6Payload pl=new IPv6Payload(bindProtocolNumber);
|
||||
pl.getData().put(buf);
|
||||
pl.getData().flip();
|
||||
ipv.setPayload(pl);
|
||||
router.insertSRHandRoutePacket(ipv);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InetAddress peek() throws IOException {
|
||||
return peekNextPacket().getSourceAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void peekData(DatagramPacket p) throws IOException {
|
||||
IPv6Packet pack=peekNextPacket();
|
||||
copyTo(pack, p);
|
||||
}
|
||||
|
||||
private void copyTo(IPv6Packet pack, DatagramPacket p) throws IOException {
|
||||
p.setAddress(pack.getSourceAddress());
|
||||
ByteBuffer buffer= ByteBuffer.wrap(p.getData(),p.getOffset(),p.getLength());
|
||||
if(ipHeaderInclude) {
|
||||
|
||||
}else {
|
||||
try {
|
||||
pack.getPayload().writeToChannel(KNEChannels.newWritableChannel(buffer));
|
||||
}catch(BufferOverflowException e) {
|
||||
|
||||
}
|
||||
}
|
||||
buffer.flip();
|
||||
p.setLength(buffer.limit());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receive(DatagramPacket p) throws IOException {
|
||||
IPv6Packet pack=pollNextPacket();
|
||||
copyTo(pack, p);
|
||||
}
|
||||
private volatile Thread parkThread;
|
||||
private IPv6Packet peekNextPacket() {
|
||||
IPv6Packet pol=null;
|
||||
while(true) {
|
||||
pol=recvQueue.peek();
|
||||
if(pol!=null) {
|
||||
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
|
||||
return pol;
|
||||
}
|
||||
parkThread=Thread.currentThread();
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
}
|
||||
private IPv6Packet pollNextPacket() {
|
||||
IPv6Packet pol=null;
|
||||
while(true) {
|
||||
pol=recvQueue.poll();
|
||||
if(pol!=null) {
|
||||
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
|
||||
return pol;
|
||||
}
|
||||
parkThread=Thread.currentThread();
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
}
|
||||
private Queue<IPv6Packet> recvQueue = new ConcurrentLinkedQueue<IPv6Packet>();
|
||||
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void accept(IPv6Packet packx) throws IOException {
|
||||
if(recvQueueUsed.get()<=inputchachesize) {
|
||||
if(recvQueue.offer(packx)) {
|
||||
recvQueueUsed.addAndGet((int) packx.getPayload().getLength());
|
||||
LockSupport.unpark(parkThread);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,16 +14,16 @@ public class KLALBVirtualSocket extends VirtualSocket {
|
||||
return (KLALBVirtualSocketImpl) super.getVirtualImpl();
|
||||
}
|
||||
|
||||
private KLALBController controler;
|
||||
private KLALBController controller;
|
||||
protected SocketChannel channel;
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
|
||||
super(controler.createVirtualImpl());
|
||||
this.controler = controler;
|
||||
this.controller = controler;
|
||||
}
|
||||
|
||||
protected KLALBController getControler() {
|
||||
return controler;
|
||||
protected KLALBController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException {
|
||||
|
||||
@@ -115,8 +115,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
|
||||
@Override
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
return ((KVSIInputStream)socket.getInputStream()).read(dsts,offset,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,8 +125,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
|
||||
@Override
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
return 0;
|
||||
return ((KVSIOutputStream)socket.getOutputStream()).write(srcs,offset,length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,4 +149,10 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
|
||||
socket.associateSocketChannel(b);
|
||||
}
|
||||
|
||||
public boolean isAutoFlush() throws IOException {
|
||||
return ((KVSIOutputStream)socket.getOutputStream()).isAutoFlush();
|
||||
}
|
||||
public void setAutoFlush(boolean b) throws IOException {
|
||||
((KVSIOutputStream)socket.getOutputStream()).setAutoFlush(b);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,11 +34,11 @@ public class PortBinder {
|
||||
this.controller = controller;
|
||||
}
|
||||
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>(65536*16);
|
||||
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>();
|
||||
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>(65536*16);
|
||||
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
|
||||
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>();
|
||||
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(65536*16);
|
||||
private volatile int portn=65535;
|
||||
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
|
||||
bindMaplock.writeLock().lock();
|
||||
@@ -205,7 +205,7 @@ public class PortBinder {
|
||||
return b;
|
||||
}*/
|
||||
public boolean distributePacketToConsumer(Inet6Address srcAddr,PortPacket packet) {
|
||||
InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport());
|
||||
InetSocketAddress local=new InetSocketAddress(controller.getSelf().getAddress(), packet.getDport());
|
||||
InetSocketAddress remote=new InetSocketAddress(srcAddr, packet.getSport());
|
||||
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
|
||||
if(bkc!=null) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SendItem {
|
||||
|
||||
private IPv6Packet packet;
|
||||
private long sendtime=System.nanoTime();
|
||||
|
||||
public SendItem(IPv6Packet packet) {
|
||||
this.packet=packet;
|
||||
}
|
||||
|
||||
public IPv6Packet getPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
public long getSendtime() {
|
||||
return sendtime;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -129,18 +129,20 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.DatagramServerSocket;
|
||||
import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.PacketRebuilder;
|
||||
import org.kne.cloud.network.PacketSpliter;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
private PacketSpliter pslr=new PacketSpliter(65535);
|
||||
private PacketRebuilder pbdr=new PacketRebuilder(1000000000);
|
||||
public class SplitedDatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
private PacketSpliter pslr;
|
||||
private PacketRebuilder pbdr;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -151,13 +153,60 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
|
||||
this.ds=connectDatagramSocket;
|
||||
bibf.limit(0);
|
||||
pslr=new PacketSpliter(new WritableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !ds.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int rem=src.remaining();
|
||||
byte[]bt=src.array();
|
||||
DatagramPacket dp=new DatagramPacket(bt,src.position(),src.limit());
|
||||
//System.out.println("SendDatagram:"+src.remaining());
|
||||
ds.send(dp);
|
||||
return rem;
|
||||
}
|
||||
},1350);
|
||||
pbdr=new PacketRebuilder(new ReadableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !ds.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
|
||||
if(ds instanceof SubDatagramSocket) {
|
||||
dp=((SubDatagramSocket) ds).receive();
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
|
||||
}else {
|
||||
dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
}
|
||||
//System.out.println("RecvDatagram:"+dp.getLength());
|
||||
return dp.getLength();
|
||||
}
|
||||
},1000000000);
|
||||
|
||||
}
|
||||
|
||||
private ByteBuffer bbf=ByteBuffer.allocate(65535);
|
||||
//private ByteBuffer bbf=ByteBuffer.allocate(65535);
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
/*@Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
//System.out.println(" TX:"+kp);
|
||||
//KLALBPacket.writeKLALBPacketToStream(dos, kp);
|
||||
KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() {
|
||||
@@ -184,47 +233,21 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
|
||||
}, kp);
|
||||
}
|
||||
}*/
|
||||
|
||||
private byte[]bc=new byte[65535];
|
||||
|
||||
private ByteBuffer bibf=ByteBuffer.allocate(65535);
|
||||
//private ByteBuffer bibf=ByteBuffer.allocate(65535);
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
/*@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
KLALBPacket kp=null;
|
||||
do {
|
||||
if(bibf.remaining()<=0) {
|
||||
bibf.clear();
|
||||
|
||||
/*DatagramPacket dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
bibf.put(dp.getData(), 0, dp.getLength());*/
|
||||
pbdr.read(bibf,new ReadableByteChannel() {
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
|
||||
if(ds instanceof SubDatagramSocket) {
|
||||
dp=((SubDatagramSocket) ds).receive();
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
|
||||
}else {
|
||||
dp=new DatagramPacket(bc, bc.length);
|
||||
ds.receive(dp);
|
||||
dst.put(dp.getData(), 0, dp.getLength());
|
||||
}
|
||||
return dp.getLength();
|
||||
}
|
||||
} );
|
||||
|
||||
pbdr.read(bibf );
|
||||
|
||||
bibf.flip();
|
||||
}
|
||||
@@ -259,7 +282,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
}while(true);
|
||||
return kp;
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
ds.close();
|
||||
@@ -280,7 +303,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
return ds.getSoTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public void flush() throws IOException {
|
||||
bbf.flip();
|
||||
//TimeDebugger tdb=new TimeDebugger();
|
||||
@@ -307,16 +330,34 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
|
||||
});
|
||||
//tdb.putTime("flushEnd");
|
||||
//tdb.print();
|
||||
/*byte[]bt=bbf.array();
|
||||
DatagramPacket dp=new DatagramPacket(bt,bbf.limit());
|
||||
ds.send(dp);*/
|
||||
|
||||
bbf.clear();
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isStream() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
incOutput(kp.remaining());
|
||||
pslr.write(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(65535);
|
||||
pbdr.read(bbf );
|
||||
bbf.flip();
|
||||
incInput(bbf.remaining());
|
||||
return bbf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
@@ -19,14 +20,19 @@ import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.kne.cloud.network.ByteBufferAllocator;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.TimeoutTimer;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
private volatile long timeoutTimer;
|
||||
private volatile boolean timerenabled=false;
|
||||
private Thread timeouter=new Thread() {
|
||||
private Runnable timeouter=new Runnable() {
|
||||
public void run() {
|
||||
timeoutTimer=System.nanoTime();
|
||||
while(connectSocket.isOpen()) {
|
||||
@@ -38,7 +44,7 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -59,29 +65,13 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
|
||||
this.connectSocket=connectSocket;
|
||||
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
||||
timeouter.start();
|
||||
ThreadTool.makeVDaemonThread("连接超时计时线程", timeouter);
|
||||
new KLALBOutputStream(Channels.newOutputStream(connectSocket));
|
||||
new KLALBInputStream(Channels.newInputStream(connectSocket));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
timeoutTimer=System.nanoTime();
|
||||
timerenabled=true;
|
||||
KLALBPacket res;
|
||||
try {
|
||||
res=KLALBPacket.readKLALBPacketFromChannel(connectSocket);
|
||||
}finally {
|
||||
timerenabled=false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -113,5 +103,136 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
incOutput(kp.limit());
|
||||
szeWrite.putInt(kp.limit());
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
connectSocket.write(new ByteBuffer[] {szeWrite,kp});
|
||||
/*
|
||||
if(connectSocket instanceof KLALBVirtualSocketChannel) {
|
||||
obj=(KLALBVirtualSocketChannel) connectSocket;
|
||||
}
|
||||
boolean isaflush=false;
|
||||
if(obj!=null) {
|
||||
isaflush=obj.isAutoFlush();
|
||||
obj.setAutoFlush(false);
|
||||
}
|
||||
|
||||
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,false);
|
||||
connectSocket.write(szeWrite);
|
||||
|
||||
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(true);
|
||||
}
|
||||
connectSocket.write(kp);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(isaflush);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
|
||||
ByteBuffer[] bbfw=new ByteBuffer[len<<1];
|
||||
for(int i=0;i<len;i++) {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
incOutput(kpp[off+i].limit());
|
||||
szeWrite.putInt(kpp[off+i].limit());
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
bbfw[i*2]=szeWrite;
|
||||
bbfw[i*2+1]=kpp[i];
|
||||
}
|
||||
connectSocket.write(bbfw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
timeoutTimer=System.nanoTime();
|
||||
timerenabled=true;
|
||||
ByteBuffer kp;
|
||||
|
||||
ByteBuffer szeRead=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeRead.limit(4);
|
||||
//szeRead.clear();
|
||||
try {
|
||||
KNEChannels.readFully(connectSocket,szeRead);
|
||||
szeRead.flip();
|
||||
int size=szeRead.getInt(0);
|
||||
kp=NetworkPacket.bufferAllocator.allocate(size);
|
||||
incInput(size);
|
||||
kp.limit(size);
|
||||
KNEChannels.readFully(connectSocket, kp);
|
||||
kp.flip();
|
||||
return kp;
|
||||
}finally {
|
||||
timerenabled=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* @Override
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
//szeWrite.clear();
|
||||
int length=(int) kp.getLength();
|
||||
incOutput(length);
|
||||
szeWrite.putInt(length);
|
||||
szeWrite.flip();
|
||||
KLALBVirtualSocketChannel obj = null;
|
||||
if(connectSocket instanceof KLALBVirtualSocketChannel) {
|
||||
obj=(KLALBVirtualSocketChannel) connectSocket;
|
||||
}
|
||||
boolean isaflush=false;
|
||||
if(obj!=null) {
|
||||
isaflush=obj.isAutoFlush();
|
||||
obj.setAutoFlush(false);
|
||||
}
|
||||
|
||||
connectSocket.write(szeWrite);
|
||||
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(true);
|
||||
}
|
||||
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
|
||||
if(obj!=null) {
|
||||
obj.setAutoFlush(isaflush);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
|
||||
szeWrite.limit(4);
|
||||
KNEChannels.readFully(connectSocket, szeWrite);
|
||||
szeWrite.flip();
|
||||
int readSize=szeWrite.getInt();
|
||||
incInput(readSize);
|
||||
return KLALBPacket.readKLALBPacketFromChannel(connectSocket);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
|
||||
public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
public class StreamKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -30,13 +31,13 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(KLALBPacket kp) throws IOException {
|
||||
out.writePacket(kp);
|
||||
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
|
||||
out.writeKLALBPacket(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KLALBPacket readPacket() throws IOException {
|
||||
return in.readPacket();
|
||||
public KLALBPacket readKLALBPacket() throws IOException {
|
||||
return in.readKLALBPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,5 +69,15 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
|
||||
public boolean isStream() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(ByteBuffer kp) throws IOException {
|
||||
out.writePacket(kp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer readPacket() throws IOException {
|
||||
return in.readPacket();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,512 @@
|
||||
package org.kne.cloud.network.klalb.ui;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.net.Inet6Address;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
|
||||
|
||||
public class GraphPanel extends JPanel {
|
||||
private Map<Inet6Address,GraphNode> nodes=new ConcurrentHashMap<Inet6Address,GraphNode>();
|
||||
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
|
||||
|
||||
public Map<Inet6Address, GraphNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public List<GraphEdgeGroup> getEdgeGroups() {
|
||||
return edgeGroups;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private double borderGap=250;
|
||||
|
||||
private double translateX,translateY;
|
||||
|
||||
private double scale=1;
|
||||
|
||||
public double getTranslateX() {
|
||||
return translateX;
|
||||
}
|
||||
|
||||
public double getTranslateY() {
|
||||
return translateY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public double getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public void setScale(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
|
||||
Graphics2D g2d=(Graphics2D)g;
|
||||
|
||||
recalcTranslate();
|
||||
g2d.scale(scale, scale);
|
||||
g2d.translate(translateX,translateY);
|
||||
double w=xmax-xmin;
|
||||
double h=ymax-ymin;
|
||||
if(w>=0&&h>=0) {
|
||||
g2d.drawRect((int)(xmin-borderGap), (int)(ymin-borderGap), (int)(w+borderGap*2), (int)(h+borderGap*2));
|
||||
}
|
||||
synchronized (edgeGroups) {
|
||||
|
||||
for( GraphEdgeGroup graphNode :edgeGroups) {
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
}
|
||||
for(GraphNode graphNode :nodes.values()) {
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public class GraphNode{
|
||||
private String text;
|
||||
private Color color;
|
||||
private double nodesize=40;
|
||||
private double x;
|
||||
private double y;
|
||||
private boolean ismarked;
|
||||
private Vector2 delta=new Vector2(0, 0);
|
||||
public GraphNode(String text, Color color, double x, double y,boolean ismarked) {
|
||||
super();
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.ismarked=ismarked;
|
||||
}
|
||||
|
||||
public double getNodesize() {
|
||||
return nodesize;
|
||||
}
|
||||
|
||||
public void setNodesize(double nodesize) {
|
||||
this.nodesize = nodesize;
|
||||
}
|
||||
|
||||
public boolean isIsmarked() {
|
||||
return ismarked;
|
||||
}
|
||||
|
||||
public void setIsmarked(boolean ismarked) {
|
||||
this.ismarked = ismarked;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public GraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g) {
|
||||
g.setColor(Color.BLACK);
|
||||
g.setStroke(new BasicStroke(2.0f));
|
||||
g.drawOval((int)(x-nodesize/2), (int)(y-nodesize/2), (int)(nodesize), (int)(nodesize));
|
||||
g.setFont(UIEnv.getFont().deriveFont(10.0f));
|
||||
|
||||
g.drawString(text, (int)(x+nodesize/2), (int)(y-nodesize/3));
|
||||
if(ismarked) {
|
||||
Vector2 pos=new Vector2(x, y);
|
||||
Vector2 v2a=new Vector2(0, -1).multi(nodesize/4);
|
||||
Vector2 v2b=new Vector2(Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
|
||||
Vector2 v2c=new Vector2(-Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
|
||||
v2a=v2a.add(pos);
|
||||
v2b=v2b.add(pos);
|
||||
v2c=v2c.add(pos);
|
||||
g.drawPolygon(new int[] {(int) v2a.x,(int) v2b.x,(int) v2c.x}, new int[] {(int) v2a.y,(int) v2b.y,(int) v2c.y}, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 getPositionVec2() {
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
public void commitDelta() {
|
||||
x+=delta.x;
|
||||
y+=delta.y;
|
||||
delta=new Vector2(0, 0);
|
||||
}
|
||||
|
||||
public void clearDelta() {
|
||||
delta=new Vector2(0, 0);
|
||||
|
||||
}
|
||||
}
|
||||
public class GraphEdge{
|
||||
private GraphNode from;
|
||||
private GraphNode to;
|
||||
LinkDirection linkPath;
|
||||
|
||||
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
|
||||
this.from=nfrom;
|
||||
this.to=nto;
|
||||
this.linkPath=lp;
|
||||
}
|
||||
|
||||
}
|
||||
public class GraphEdgeGroup{
|
||||
private double length=100;
|
||||
private double gap=12;
|
||||
private boolean isShortest=false;
|
||||
private GraphNode nodeA,nodeB;
|
||||
private List<GraphEdge> edges=new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
public double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public double getGap() {
|
||||
return gap;
|
||||
}
|
||||
|
||||
public void setGap(double gap) {
|
||||
this.gap = gap;
|
||||
}
|
||||
|
||||
public boolean match(GraphNode a,GraphNode b) {
|
||||
if(a.equals( nodeA)&&b.equals( nodeB))
|
||||
return true;
|
||||
if(b.equals( nodeA)&&a.equals( nodeB))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super();
|
||||
this.nodeA = nodeA;
|
||||
this.nodeB = nodeB;
|
||||
}
|
||||
|
||||
public boolean isShortest() {
|
||||
return isShortest;
|
||||
}
|
||||
|
||||
public void setShortest(boolean isShortest) {
|
||||
this.isShortest = isShortest;
|
||||
}
|
||||
|
||||
public List<GraphEdge> getPaths() {
|
||||
return getEdges();
|
||||
}
|
||||
public void paint(Graphics2D g) {
|
||||
|
||||
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
|
||||
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
|
||||
Vector2 vecDir=nodeBv.subtract(nodeAv);
|
||||
Vector2 vecDirnor=vecDir.normalize();
|
||||
Vector2 vecRA=vecDirnor.multi(nodeA.getNodesize()/2);
|
||||
Vector2 vecRB=vecDirnor.multi(nodeB.getNodesize()/2);
|
||||
|
||||
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
|
||||
|
||||
//所有线路完整显示
|
||||
/*
|
||||
double width=gap*(edges.size()-1);
|
||||
//System.out.println(width);
|
||||
|
||||
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
|
||||
|
||||
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
|
||||
//System.out.println(vec90nor);
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
|
||||
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
}
|
||||
*/
|
||||
long totalupspeed=0;
|
||||
long usedupspeed=0;
|
||||
long totaldownspeed=0;
|
||||
long useddownspeed=0;
|
||||
for(GraphEdge graphEdge :getEdges()) {
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) ) {
|
||||
totalupspeed+=graphEdge.linkPath.getBandwidth();
|
||||
usedupspeed+=graphEdge.linkPath.getSpeed();
|
||||
}
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) ) {
|
||||
totaldownspeed+=graphEdge.linkPath.getBandwidth();
|
||||
useddownspeed+=graphEdge.linkPath.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totalupspeed/10.0/1024.0))));
|
||||
|
||||
double width=gap*1;
|
||||
Vector2 startPoint=nodeAv.add(vecRA).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecRB).add(vec90nor.multi(width/2));
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentagex(usedupspeed*100f/totalupspeed));
|
||||
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
|
||||
|
||||
|
||||
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totaldownspeed/10.0/1024.0))));
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentagex(useddownspeed*100f/totaldownspeed));
|
||||
|
||||
|
||||
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
|
||||
if(isShortest) {
|
||||
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,3,0,3}, 0);
|
||||
g.setStroke(dotted);
|
||||
g.setColor(Color.BLUE);
|
||||
g.drawLine((int)nodeA.getX(), (int)nodeA.getY(), (int)nodeB.getX(), (int)nodeB.getY());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public List<GraphEdge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// 计算
|
||||
public static double[] rotateVec(int px, int py, double ang,
|
||||
boolean isChLen, double newLen) {
|
||||
|
||||
double mathstr[] = new double[2];
|
||||
// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
|
||||
double vx = px * Math.cos(ang) - py * Math.sin(ang);
|
||||
double vy = px * Math.sin(ang) + py * Math.cos(ang);
|
||||
if (isChLen) {
|
||||
double d = Math.sqrt(vx * vx + vy * vy);
|
||||
vx = vx / d * newLen;
|
||||
vy = vy / d * newLen;
|
||||
mathstr[0] = vx;
|
||||
mathstr[1] = vy;
|
||||
}
|
||||
return mathstr;
|
||||
}
|
||||
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
|
||||
{
|
||||
|
||||
double H = 13; // 箭头高度
|
||||
double L = 8; // 底边的一半
|
||||
int x3 = 0;
|
||||
int y3 = 0;
|
||||
int x4 = 0;
|
||||
int y4 = 0;
|
||||
double awrad = Math.atan(L / H); // 箭头角度
|
||||
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
|
||||
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
|
||||
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
|
||||
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
|
||||
double y_3 = ey - arrXY_1[1];
|
||||
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
|
||||
double y_4 = ey - arrXY_2[1];
|
||||
|
||||
Double X3 = new Double(x_3);
|
||||
x3 = X3.intValue();
|
||||
Double Y3 = new Double(y_3);
|
||||
y3 = Y3.intValue();
|
||||
Double X4 = new Double(x_4);
|
||||
x4 = X4.intValue();
|
||||
Double Y4 = new Double(y_4);
|
||||
y4 = Y4.intValue();
|
||||
// 画线
|
||||
g2.drawLine(sx, sy, ex, ey);
|
||||
//
|
||||
GeneralPath triangle = new GeneralPath();
|
||||
triangle.moveTo(ex, ey);
|
||||
triangle.lineTo(x3, y3);
|
||||
triangle.lineTo(x4, y4);
|
||||
triangle.closePath();
|
||||
//实心箭头
|
||||
g2.fill(triangle);
|
||||
//非实心箭头
|
||||
//g2.draw(triangle);
|
||||
|
||||
}
|
||||
|
||||
protected void loadNodes() {
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
private void recalcTranslate() {
|
||||
double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
|
||||
double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
|
||||
for(GraphNode graphNode:nodes.values()) {
|
||||
xmin=Math.min(xmin, graphNode.x);
|
||||
xmax=Math.max(xmax, graphNode.x);
|
||||
ymin=Math.min(ymin, graphNode.y);
|
||||
ymax=Math.max(ymax, graphNode.y);
|
||||
}
|
||||
this.xmin=xmin;
|
||||
this.xmax=xmax;
|
||||
this.ymin=ymin;
|
||||
this.ymax=ymax;
|
||||
if(xmin!=Double.MAX_VALUE) {
|
||||
translateX=-xmin+borderGap;
|
||||
translateY= -ymin+borderGap;
|
||||
}
|
||||
}
|
||||
|
||||
private double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
|
||||
private double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
|
||||
public void updateBounds() {
|
||||
recalcTranslate();
|
||||
|
||||
if(xmin!=Double.MAX_VALUE) {
|
||||
Dimension d=new Dimension((int)(((xmax-xmin)+borderGap*2)*scale),(int)(((ymax-ymin)+borderGap*2)*scale) );
|
||||
setPreferredSize(d);
|
||||
setSize(d);
|
||||
}
|
||||
}
|
||||
|
||||
public void runPhy() {
|
||||
for( GraphNode graphEdgeGroup :nodes.values()) {
|
||||
Vector2 vecpos=graphEdgeGroup.getPositionVec2();
|
||||
Vector2 vec=new Vector2(0, 0);
|
||||
for (Iterator<GraphNode> iteratorx =nodes.values().iterator(); iteratorx.hasNext();) {
|
||||
GraphNode graphEdgeGroup2 = (GraphNode) iteratorx.next();
|
||||
if(graphEdgeGroup2!=graphEdgeGroup) {
|
||||
Vector2 vecpos2=graphEdgeGroup2.getPositionVec2();
|
||||
Vector2 sub=vecpos.subtract(vecpos2);
|
||||
double distance=sub.Length();
|
||||
Vector2 dic=sub.normalize();
|
||||
vec=vec.add(dic.multi(Math.min(10.0/distance,10.0)));
|
||||
}
|
||||
}
|
||||
graphEdgeGroup.delta=graphEdgeGroup.delta.add(vec);
|
||||
}
|
||||
synchronized (edgeGroups) {
|
||||
|
||||
for(GraphEdgeGroup graphEdgeGroup :edgeGroups) {
|
||||
GraphNode na=graphEdgeGroup.nodeA;
|
||||
GraphNode nb=graphEdgeGroup.nodeB;
|
||||
Vector2 veca=na.getPositionVec2();
|
||||
Vector2 vecb=nb.getPositionVec2();
|
||||
Vector2 sub=veca.subtract(vecb);
|
||||
double distance=sub.Length();
|
||||
double length=graphEdgeGroup.getLength()+na.getNodesize()/2+nb.getNodesize()/2;
|
||||
|
||||
//System.out.println(length);
|
||||
if(distance>length) {
|
||||
Vector2 dicb=sub.normalize().multi((distance-length)/3);
|
||||
Vector2 dica=dicb.opposite();
|
||||
na.delta=na.delta.add(dica);
|
||||
nb.delta=nb.delta.add(dicb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( GraphNode graphEdgeGroup:nodes.values()) {
|
||||
|
||||
graphEdgeGroup.commitDelta();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Random r=new Random();
|
||||
public Vector2 getRandomPos() {
|
||||
double x,y;
|
||||
if(xmin>=xmax) {
|
||||
x=r.nextDouble();
|
||||
}else {
|
||||
x=r.nextDouble(xmin, xmax);
|
||||
}
|
||||
if(ymin>=ymax) {
|
||||
y=r.nextDouble();
|
||||
}else {
|
||||
y=r.nextDouble(ymin, ymax);
|
||||
}
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,12 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Point;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.TrayIcon;
|
||||
@@ -18,7 +21,14 @@ import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@@ -32,7 +42,9 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.jfree.chart.ChartPanel;
|
||||
@@ -45,11 +57,14 @@ import org.jfree.chart.plot.dial.StandardDialRange;
|
||||
import org.jfree.chart.plot.dial.StandardDialScale;
|
||||
import org.jfree.chart.ui.RectangleEdge;
|
||||
import org.jfree.data.general.DefaultValueDataset;
|
||||
import org.kne.cloud.klalb.uitool.SettingItem;
|
||||
import org.kne.cloud.klalb.uitool.TextSettingItem;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.klalb.CONST;
|
||||
import org.kne.cloud.network.klalb.KLALBController;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.klalb.ui.GraphPanel.GraphNode;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.ui.XFrame;
|
||||
import org.kne.ui.YScrollPane;
|
||||
@@ -63,8 +78,6 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
private TrayIcon ti;
|
||||
|
||||
private long rate=200;
|
||||
|
||||
private Timer t,t2,t3;
|
||||
|
||||
private JCheckBoxMenuItem showoffline;
|
||||
@@ -103,13 +116,16 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
private DefaultValueDataset downEfficiency;*/
|
||||
|
||||
private YScrollPane ysp;
|
||||
private YScrollPane ysp,yspc;
|
||||
|
||||
private JTextField devicesOnline;
|
||||
private JTextField textField;
|
||||
private JTextField addressField;
|
||||
private JTextField addressField2;
|
||||
private JTextField asnField;
|
||||
|
||||
private NetworkGraphPanel graph;
|
||||
private JTextField textFieldLocate;
|
||||
|
||||
|
||||
/**
|
||||
@@ -771,11 +787,135 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
JPanel panel_4 = new JPanel();
|
||||
panel_3.add(panel_4, BorderLayout.NORTH);
|
||||
panel_4.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
|
||||
|
||||
textFieldLocate = new JTextField();
|
||||
panel_4.add(textFieldLocate, BorderLayout.CENTER);
|
||||
textFieldLocate.setColumns(10);
|
||||
|
||||
graph = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol());
|
||||
graph.setOpaque(false);
|
||||
JScrollPane jsp=new JScrollPane(graph);
|
||||
JScrollPane jsp=new JScrollPane();jsp.setWheelScrollingEnabled(false);
|
||||
jsp.setViewportView(graph);
|
||||
MouseAdapter ma = new MouseAdapter() {
|
||||
|
||||
private Point origin;
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
origin = new Point(e.getPoint());
|
||||
//System.out.println(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (origin != null) {
|
||||
//System.out.println(e);
|
||||
//JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, jsp);
|
||||
//if (viewPort != null) {
|
||||
int deltaX = origin.x - e.getX();
|
||||
int deltaY = origin.y - e.getY();
|
||||
|
||||
Rectangle view = jsp.getViewport().getVisibleRect();
|
||||
view.x += deltaX;
|
||||
view.y += deltaY;
|
||||
|
||||
jsp.getViewport().scrollRectToVisible(view);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
graph.addMouseWheelListener(new MouseWheelListener() {
|
||||
private double scaleidx=1;
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
int val= e.getWheelRotation();
|
||||
double scaleidxold=scaleidx;
|
||||
scaleidx*=Math.pow(1.1, val);
|
||||
if(scaleidx>5) {
|
||||
scaleidx=5;
|
||||
}
|
||||
if(scaleidx<0.1) {
|
||||
scaleidx=0.1;
|
||||
}
|
||||
double pow=scaleidx/scaleidxold;
|
||||
Point pos = jsp.getViewport().getViewPosition();
|
||||
double canvasX=e.getX();
|
||||
double canvasY=e.getY();
|
||||
double w=graph.getWidth();
|
||||
double h=graph.getHeight();
|
||||
double percentX=canvasX/w;
|
||||
double percentY=canvasY/h;
|
||||
graph.setScale(scaleidx);
|
||||
graph.updateBounds();
|
||||
double newcanvasX=percentX*w*pow;
|
||||
double newcanvasY=percentY*h*pow;
|
||||
double dx= newcanvasX-canvasX;
|
||||
double dy=newcanvasY-canvasY;
|
||||
//System.out.println(dx+" "+dy);
|
||||
pos.x+=dx;
|
||||
pos.y+=dy ;
|
||||
jsp.getViewport().setViewPosition(pos);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
JButton btnLocate = new JButton("Locate");
|
||||
btnLocate.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String text= textFieldLocate.getText();
|
||||
try {
|
||||
Inet6Address addr=(Inet6Address) Inet6Address.getByName(text);
|
||||
GraphNode node= graph.getNodes().get(addr);
|
||||
if(node==null) {
|
||||
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Address not found", "Warning", JOptionPane.WARNING_MESSAGE);
|
||||
}else {
|
||||
Point pos = new Point();
|
||||
graph.updateBounds();
|
||||
Dimension dim= jsp.getViewport().getExtentSize();
|
||||
// System.out.println(dim);
|
||||
pos.x =(int) ((node.getX()+graph.getTranslateX())*graph.getScale()-dim.width/2);
|
||||
pos.y =(int) ((node.getY()+graph.getTranslateY())*graph.getScale()-dim.height/2);
|
||||
jsp.getViewport().setViewPosition(pos);
|
||||
}
|
||||
} catch (UnknownHostException e1) {
|
||||
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Input format error", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
panel_4.add(btnLocate, BorderLayout.EAST);
|
||||
|
||||
JButton btnHome = new JButton("Home");
|
||||
btnHome.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textFieldLocate.setText(addressField.getText());
|
||||
btnLocate.doClick();
|
||||
}
|
||||
});
|
||||
panel_4.add(btnHome, BorderLayout.WEST);
|
||||
graph.addMouseListener(ma);
|
||||
graph.addMouseMotionListener(ma);
|
||||
panel_3.add(jsp, BorderLayout.CENTER);
|
||||
yspc = new YScrollPane(730);
|
||||
yspc.setOpaque(false);
|
||||
JPanel configsPanel = new JPanel();
|
||||
configsPanel.setLayout(new BorderLayout(0, 0));
|
||||
configsPanel.add(yspc);
|
||||
addSettingItems(yspc);
|
||||
JButton btnSave = new JButton("Save settings");
|
||||
yspc.add(btnSave, BorderLayout.NORTH);
|
||||
tabbedPane.addTab("Settings", null, configsPanel, null);
|
||||
configsPanel.setOpaque(false);
|
||||
textField.addKeyListener(new KeyListener() {
|
||||
|
||||
@Override
|
||||
@@ -795,7 +935,43 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
}
|
||||
}
|
||||
});
|
||||
textFieldLocate.addKeyListener(new KeyListener() {
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
|
||||
btnLocate.doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private void addSettingItems(YScrollPane settings) {
|
||||
SettingItem si=new SettingItem("Basic settings",UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD),CONST.itemwidth,CONST.settingheight);
|
||||
settings.getView().add(si);
|
||||
|
||||
TextSettingItem addr6=new TextSettingItem("IPv6 address",CONST.itemwidth,CONST.settingheight);
|
||||
addressField2=addr6.getTextField();
|
||||
settings.getView().add(addr6);
|
||||
|
||||
TextSettingItem asn=new TextSettingItem("AS number",CONST.itemwidth,CONST.settingheight);
|
||||
asnField=asn.getTextField();
|
||||
settings.getView().add(asn);
|
||||
|
||||
settings.updateScrool();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
|
||||
if(tsk!=null) {
|
||||
tsk.cancel();
|
||||
@@ -920,13 +1096,22 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
if(!contt.equals(devicesOnline.getText())) {
|
||||
devicesOnline.setText(contt);
|
||||
}
|
||||
String address=kc.getSelf().getHostAddress();
|
||||
String address=kc.getSelf().getAddress().getHostAddress();
|
||||
if(!address.equals(addressField.getText())) {
|
||||
addressField.setText(address);
|
||||
}
|
||||
if(!address.equals(addressField2.getText())) {
|
||||
addressField2.setText(address);
|
||||
}
|
||||
|
||||
String asnstr=Long.toString( kc.getIpv6Router().getASN());
|
||||
if(!asnstr.equals(asnField.getText())) {
|
||||
asnField.setText(asnstr);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
t2.scheduleAtFixedRate(tsk2, 200, 50);
|
||||
t2.scheduleAtFixedRate(tsk2, 200, 100);
|
||||
|
||||
if(tsk3!=null) {
|
||||
tsk3.cancel();
|
||||
@@ -970,7 +1155,7 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
}
|
||||
}
|
||||
};
|
||||
t3.scheduleAtFixedRate(tsk4, 200, 10);
|
||||
t3.scheduleAtFixedRate(tsk4, 200, 20);
|
||||
if(tsk5!=null) {
|
||||
tsk5.cancel();
|
||||
}
|
||||
@@ -978,11 +1163,15 @@ public class KLALBStateGUI2 extends XFrame {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(graph.isVisible())
|
||||
graph.loadNodes();
|
||||
graph.runPhy();
|
||||
if(graph.isVisible()) {
|
||||
graph.repaint();
|
||||
graph.revalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.scheduleAtFixedRate(tsk5, 200, 2000);
|
||||
t.scheduleAtFixedRate(tsk5, 200, 100);
|
||||
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.kne.cloud.network.klalb.ui;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
@@ -14,6 +15,7 @@ import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -26,240 +28,80 @@ import java.util.Set;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
|
||||
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
|
||||
|
||||
public class NetworkGraphPanel extends JPanel {
|
||||
public class NetworkGraphPanel extends GraphPanel {
|
||||
private KLALBRoutingProtocol routingProtocol;
|
||||
private Map<Inet6Address,GraphNode> nodes=new HashMap<Inet6Address,GraphNode>();
|
||||
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
|
||||
private static final int nodesize=80;
|
||||
private class GraphNode{
|
||||
private String text;
|
||||
private Color color;
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public GraphNode(String text, Color color, int x, int y) {
|
||||
super();
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public GraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g) {
|
||||
g.setColor(Color.BLACK);
|
||||
g.setStroke(new BasicStroke(2.0f));
|
||||
g.drawOval(x-nodesize/2, y-nodesize/2, nodesize, nodesize);
|
||||
g.setFont(UIEnv.getFont().deriveFont(10.0f));
|
||||
g.drawString(text, x+nodesize/2, y-nodesize/3);
|
||||
}
|
||||
}
|
||||
private class GraphEdge{
|
||||
private GraphNode from;
|
||||
private GraphNode to;
|
||||
private LinkDirection linkPath;
|
||||
|
||||
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
|
||||
this.from=nfrom;
|
||||
this.to=nto;
|
||||
this.linkPath=lp;
|
||||
}
|
||||
|
||||
}
|
||||
private class GraphEdgeGroup{
|
||||
private static final double gap=3;
|
||||
private GraphNode nodeA,nodeB;
|
||||
private List<GraphEdge> edges=new ArrayList<>();
|
||||
|
||||
private boolean match(GraphNode a,GraphNode b) {
|
||||
if(a.equals( nodeA)&&b.equals( nodeB))
|
||||
return true;
|
||||
if(b.equals( nodeA)&&a.equals( nodeB))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super();
|
||||
this.nodeA = nodeA;
|
||||
this.nodeB = nodeB;
|
||||
}
|
||||
public List<GraphEdge> getPaths() {
|
||||
return edges;
|
||||
}
|
||||
public void paint(Graphics2D g) {
|
||||
g.setStroke(new BasicStroke(1.0f));
|
||||
|
||||
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
|
||||
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
|
||||
Vector2 vecDir=nodeBv.subtract(nodeAv);
|
||||
Vector2 vecDirnor=vecDir.normalize();
|
||||
Vector2 vecR=vecDirnor.multi(nodesize/2);
|
||||
|
||||
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
|
||||
|
||||
double width=gap*(edges.size()-1);
|
||||
|
||||
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
|
||||
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
|
||||
//System.out.println(width);
|
||||
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
|
||||
//System.out.println(vec90nor);
|
||||
|
||||
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
|
||||
|
||||
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
|
||||
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
|
||||
|
||||
|
||||
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
|
||||
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
|
||||
|
||||
startPoint=startPoint.subtract(vec90nor.multi(gap));
|
||||
endPoint=endPoint.subtract(vec90nor.multi(gap));
|
||||
}
|
||||
|
||||
//g.drawLine(nodeA.getX(), nodeA.getY(), nodeB.getX(), nodeB.getY());
|
||||
|
||||
}
|
||||
|
||||
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
|
||||
{
|
||||
|
||||
double H = 5; // 箭头高度
|
||||
double L = 2; // 底边的一半
|
||||
int x3 = 0;
|
||||
int y3 = 0;
|
||||
int x4 = 0;
|
||||
int y4 = 0;
|
||||
double awrad = Math.atan(L / H); // 箭头角度
|
||||
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
|
||||
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
|
||||
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
|
||||
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
|
||||
double y_3 = ey - arrXY_1[1];
|
||||
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
|
||||
double y_4 = ey - arrXY_2[1];
|
||||
|
||||
Double X3 = new Double(x_3);
|
||||
x3 = X3.intValue();
|
||||
Double Y3 = new Double(y_3);
|
||||
y3 = Y3.intValue();
|
||||
Double X4 = new Double(x_4);
|
||||
x4 = X4.intValue();
|
||||
Double Y4 = new Double(y_4);
|
||||
y4 = Y4.intValue();
|
||||
// 画线
|
||||
g2.drawLine(sx, sy, ex, ey);
|
||||
//
|
||||
GeneralPath triangle = new GeneralPath();
|
||||
triangle.moveTo(ex, ey);
|
||||
triangle.lineTo(x3, y3);
|
||||
triangle.lineTo(x4, y4);
|
||||
triangle.closePath();
|
||||
//实心箭头
|
||||
g2.fill(triangle);
|
||||
//非实心箭头
|
||||
//g2.draw(triangle);
|
||||
|
||||
}
|
||||
|
||||
// 计算
|
||||
public static double[] rotateVec(int px, int py, double ang,
|
||||
boolean isChLen, double newLen) {
|
||||
|
||||
double mathstr[] = new double[2];
|
||||
// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
|
||||
double vx = px * Math.cos(ang) - py * Math.sin(ang);
|
||||
double vy = px * Math.sin(ang) + py * Math.cos(ang);
|
||||
if (isChLen) {
|
||||
double d = Math.sqrt(vx * vx + vy * vy);
|
||||
vx = vx / d * newLen;
|
||||
vy = vy / d * newLen;
|
||||
mathstr[0] = vx;
|
||||
mathstr[1] = vy;
|
||||
}
|
||||
return mathstr;
|
||||
}
|
||||
|
||||
}
|
||||
public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) {
|
||||
super();
|
||||
this.routingProtocol = routingProtocol;
|
||||
//setSize(10000, 10000);
|
||||
//setPreferredSize(getSize());
|
||||
}
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
loadNodes();
|
||||
|
||||
Graphics2D g2d=(Graphics2D)g;
|
||||
|
||||
for (Iterator<GraphEdgeGroup> iterator = edgeGroups.iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next();
|
||||
graphNode.paint(g2d);
|
||||
|
||||
private class InetGraphNode extends GraphNode{
|
||||
|
||||
private InetAddress address;
|
||||
|
||||
public InetGraphNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InetGraphNode(InetAddress address, Color color, double x, double y, boolean ismarked) {
|
||||
super(getText(address), color, x, y, ismarked);
|
||||
this.address=address;
|
||||
}
|
||||
|
||||
private static String getText(InetAddress address2) {
|
||||
String text;
|
||||
if(address2 instanceof Inet6Address) {
|
||||
text=KLALBUtils.parseAbbrIPv6(address2.getHostAddress());
|
||||
}else {
|
||||
text=address2.getHostAddress();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(InetAddress address) {
|
||||
this.address = address;
|
||||
super.setText(getText(address));
|
||||
}
|
||||
|
||||
for (Iterator<GraphNode> iterator = nodes.values().iterator(); iterator.hasNext();) {
|
||||
GraphNode graphNode = (GraphNode) iterator.next();
|
||||
graphNode.paint(g2d);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Random r=new Random();
|
||||
private void loadNodes() {
|
||||
|
||||
private double nsPerPixel=1000L;
|
||||
private class InetGraphEdgeGroup extends GraphEdgeGroup{
|
||||
public InetGraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
|
||||
super(nodeA, nodeB);
|
||||
}
|
||||
|
||||
public void updateLength() {
|
||||
long mindelay=Long.MAX_VALUE>>2;
|
||||
for (Iterator<GraphEdge> iterator = getEdges().iterator(); iterator.hasNext();) {
|
||||
GraphEdge graphEdge = (GraphEdge) iterator.next();
|
||||
mindelay=Math.min(mindelay, graphEdge.linkPath.getDelay());
|
||||
}
|
||||
setLength(mindelay/nsPerPixel);
|
||||
}
|
||||
}
|
||||
protected void loadNodes() {
|
||||
Map<Inet6Address, Long> addr= routingProtocol.getAddresses();
|
||||
Set<Inet6Address> ks=addr.keySet();
|
||||
for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
if(!nodes.containsKey(inet6Address))
|
||||
nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50)));
|
||||
}
|
||||
Set<Inet6Address> kns=nodes.keySet();
|
||||
if(!getNodes().containsKey(inet6Address)) {
|
||||
Vector2 v2pos=super.getRandomPos();
|
||||
getNodes().put(inet6Address,new InetGraphNode(inet6Address,Color.BLACK,v2pos.x,v2pos.y,inet6Address.equals(routingProtocol.getRouter().getLocator().getAddress())));
|
||||
}
|
||||
}
|
||||
Set<Inet6Address> kns=getNodes().keySet();
|
||||
for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
if(!addr.containsKey(inet6Address)) {
|
||||
@@ -267,32 +109,53 @@ public class NetworkGraphPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
//System.out.println("------------------------------------");
|
||||
edgeGroups.clear();
|
||||
Map<Inet6Address, Set<LinkDirection>> addr1= routingProtocol.getPaths();
|
||||
Set<Entry<Inet6Address, Set<LinkDirection>>> salink=addr1.entrySet();
|
||||
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
|
||||
Set<LinkDirection>lps=entry.getValue();
|
||||
synchronized (getEdgeGroups()) {
|
||||
|
||||
getEdgeGroups().clear();
|
||||
Map<Inet6Address, List<LinkDirection>> addr1= routingProtocol.getPaths();
|
||||
Set<Entry<Inet6Address, List<LinkDirection>>> salink=addr1.entrySet();
|
||||
for (Iterator<Entry<Inet6Address, List<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, List<LinkDirection>> entry = (Entry<Inet6Address, List<LinkDirection>>) iterator.next();
|
||||
List<LinkDirection>lps=entry.getValue();
|
||||
for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
|
||||
LinkDirection linkPath = (LinkDirection) iterator2.next();
|
||||
//System.out.println(linkPath);
|
||||
GraphNode nfrom=nodes.get(linkPath.getFromLocator());
|
||||
GraphNode nto=nodes.get(linkPath.getToLocator());
|
||||
InetGraphNode nfrom=(InetGraphNode) getNodes().get(linkPath.getFromLocator());
|
||||
InetGraphNode nto=(InetGraphNode) getNodes().get(linkPath.getToLocator());
|
||||
if(nfrom!=null&&nto!=null) {
|
||||
GraphEdgeGroup group=getGroup(nfrom, nto);
|
||||
group.getPaths().add(new GraphEdge(nfrom,nto,linkPath));
|
||||
|
||||
|
||||
GraphEdge ge=new GraphEdge(nfrom,nto,linkPath);
|
||||
group.getPaths().add(ge);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
|
||||
((InetGraphEdgeGroup) graphEdgeGroup).updateLength();
|
||||
}
|
||||
}
|
||||
super.loadNodes();
|
||||
}
|
||||
|
||||
private GraphEdgeGroup getGroup(GraphNode a,GraphNode b) {
|
||||
for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) {
|
||||
private GraphEdgeGroup getGroup(InetGraphNode a,InetGraphNode b) {
|
||||
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
|
||||
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
|
||||
if(graphEdgeGroup.match(a,b)) {
|
||||
return graphEdgeGroup;
|
||||
}
|
||||
}
|
||||
GraphEdgeGroup ng=new GraphEdgeGroup(a, b);
|
||||
edgeGroups.add(ng);
|
||||
GraphEdgeGroup ng=new InetGraphEdgeGroup(a, b);
|
||||
Inet6Address aprev= routingProtocol.getDijkstraPrevNode((Inet6Address) a.getAddress());
|
||||
Inet6Address bprev= routingProtocol.getDijkstraPrevNode((Inet6Address) b.getAddress());
|
||||
|
||||
if( b.getAddress().equals(aprev)||a.getAddress().equals(bprev)) {
|
||||
ng.setShortest(true);
|
||||
}
|
||||
getEdgeGroups().add(ng);
|
||||
return ng;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.klalb.CONST;
|
||||
import org.kne.cloud.network.klalb.KLALBController;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
@@ -93,7 +94,7 @@ public class TPanel2 extends JPanel {
|
||||
targup.setHorizontalTextPosition(SwingConstants.LEFT);
|
||||
|
||||
setBorder(new LineBorder(Color.LIGHT_GRAY));
|
||||
setSize(720, 45);
|
||||
setSize(CONST.itemwidth, CONST.linepanelheight);
|
||||
setPreferredSize(getSize());
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
|
||||
@@ -90,7 +90,7 @@ public class SimpleKLALBMinecraftServer {
|
||||
try {
|
||||
s=mpsa2.connectSocket();
|
||||
MinecraftSocketBridge dsb=new MinecraftSocketBridge(pds, s);
|
||||
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
|
||||
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf().getAddress();},()->{return 23333;}));
|
||||
dsb.run();
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
@@ -129,7 +129,7 @@ public class SimpleKLALBMinecraftServer {
|
||||
//soc.setTcpNoDelay(true);
|
||||
//((KLALBVirtualSocket) soc).setCompress(1);
|
||||
MinecraftSocketBridge dsb=new MinecraftSocketBridge(soc, s);
|
||||
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
|
||||
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf().getAddress();},()->{return 23333;}));
|
||||
//dsb.getSab().setDelay(1);
|
||||
dsb.run();
|
||||
/*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc);
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.kne.cloud.network.monitor;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface MonitorData {
|
||||
public interface MonitorData extends Cloneable {
|
||||
public static final int OFFLINE=0;
|
||||
public static final int CONNECTING=1;
|
||||
public static final int ONLINE=2;
|
||||
@@ -30,4 +30,6 @@ public double getReliability();
|
||||
throw new IllegalArgumentException("Unknown state:"+state);
|
||||
}
|
||||
}
|
||||
public Object clone() throws CloneNotSupportedException;
|
||||
|
||||
}
|
||||
|
||||
@@ -86,4 +86,9 @@ private TimerTask ptt=new TimerTask() {
|
||||
public double getReliability() {
|
||||
return reliability;
|
||||
}
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
||||
}
|
||||
|
||||
protected void createTask1() {
|
||||
getTimer().scheduleAtFixedRate(tmt1, 0, 1000);
|
||||
getTimer().scheduleAtFixedRate(tmt1, 0, 500);
|
||||
}
|
||||
protected void createTask2() {
|
||||
getTimer().scheduleAtFixedRate(tmt2, 0, 5000);
|
||||
@@ -123,24 +123,24 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
||||
if(inTraffic!=null) {
|
||||
long i=inTraffic.get()-inTrafficOld;
|
||||
inTrafficOld =inTraffic.get();
|
||||
inSpeed= i*1000000000/d;
|
||||
inSpeed= (long) (i*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(outTraffic!=null) {
|
||||
long o=outTraffic.get()-outTrafficOld;
|
||||
outTrafficOld =outTraffic.get();
|
||||
outSpeed= o*1000000000/d;
|
||||
outSpeed= (long) (o*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(inCounter!=null) {
|
||||
long i=inCounter.get()-inCounterOld;
|
||||
inCounterOld =inCounter.get();
|
||||
inPPS= i*1000000000/d;
|
||||
inPPS= (long) (i*1000000000.0/d);
|
||||
}
|
||||
if(outCounter!=null) {
|
||||
long i=outCounter.get()-outCounterOld;
|
||||
outCounterOld =outCounter.get();
|
||||
outPPS= i*1000000000/d;
|
||||
outPPS= (long) (i*1000000000.0/d);
|
||||
}
|
||||
}
|
||||
if(outSpeed>=outSpeedMax) {
|
||||
@@ -182,25 +182,25 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
||||
if(inTraffic!=null) {
|
||||
long i=inTraffic.get()-inTrafficOld1;
|
||||
inTrafficOld1 =inTraffic.get();
|
||||
inSpeedAvg= i*1000000000/d;
|
||||
inSpeedAvg= (long) (i*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(outTraffic!=null) {
|
||||
long o=outTraffic.get()-outTrafficOld1;
|
||||
outTrafficOld1 =outTraffic.get();
|
||||
outSpeedAvg= o*1000000000/d;
|
||||
outSpeedAvg= (long) (o*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(inCounter!=null) {
|
||||
long i=inCounter.get()-inCounterOld1;
|
||||
inCounterOld1 =inCounter.get();
|
||||
inPPSAvg= i*1000000000/d;
|
||||
inPPSAvg= (long) (i*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(outCounter!=null) {
|
||||
long o=outCounter.get()-outCounterOld1;
|
||||
outCounterOld1 =outCounter.get();
|
||||
outPPSAvg= o*1000000000/d;
|
||||
outPPSAvg= (long) (o*1000000000.0/d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,13 +218,13 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
||||
if(inTraffic!=null) {
|
||||
long i=inTraffic.get()-inTrafficOld2;
|
||||
inTrafficOld2 =inTraffic.get();
|
||||
inSpeedAvg2= i*1000000000/d;
|
||||
inSpeedAvg2= (long) (i*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(outTraffic!=null) {
|
||||
long o=outTraffic.get()-outTrafficOld2;
|
||||
outTrafficOld2 =outTraffic.get();
|
||||
outSpeedAvg2= o*1000000000/d;
|
||||
outSpeedAvg2= (long) (o*1000000000.0/d);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,13 +232,13 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
|
||||
if(inCounter!=null) {
|
||||
long i=inCounter.get()-inCounterOld2;
|
||||
inCounterOld2 =inCounter.get();
|
||||
inPPSAvg2= i*1000000000/d;
|
||||
inPPSAvg2= (long) (i*1000000000.0/d);
|
||||
}
|
||||
|
||||
if(outCounter!=null) {
|
||||
long o=outCounter.get()-outCounterOld2;
|
||||
outCounterOld2 =outCounter.get();
|
||||
outPPSAvg2= o*1000000000/d;
|
||||
outPPSAvg2= (long) (o*1000000000.0/d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.kne.cloud.network.klalb.KLALBPacketLink;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.klalb.PINGPacket;
|
||||
import org.kne.cloud.network.klalb.PONGPacket;
|
||||
import org.kne.cloud.network.klalb.TESTPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRACKPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRREQPacket;
|
||||
@@ -74,12 +73,13 @@ public class Kperf implements Runnable{
|
||||
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
|
||||
|
||||
private static long MIN_SPEED=64*1024L;
|
||||
private SpeedLimiter congress = new SpeedLimiter(0,10000000L);
|
||||
private SpeedLimiter congress = new SpeedLimiter(10000000L);
|
||||
private long congressSpeed = 0;
|
||||
private double loadPercent = 1.01;
|
||||
|
||||
private volatile int testSize=0;
|
||||
//kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564
|
||||
|
||||
KLALBPacket testPacket=null;
|
||||
//kperf {KLALB_Stream}[2486:1:f189:7589:f1f7:6f5e:b2eb:1]:4564
|
||||
//kperf {KLALB_Stream}[2486:1::8888]:4564
|
||||
@Override
|
||||
public void run() {
|
||||
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> {
|
||||
@@ -100,14 +100,14 @@ public class Kperf implements Runnable{
|
||||
System.out.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0);
|
||||
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);*/
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
|
||||
*/
|
||||
startTime=System.nanoTime();
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试2/4:下载带宽测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=60000;
|
||||
testPacket=new TESTNPacket(60000);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
|
||||
@@ -118,7 +118,7 @@ public class Kperf implements Runnable{
|
||||
}else {
|
||||
System.out.println("测试2/4:上传带宽测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=60000;
|
||||
testPacket=new TESTNPacket(60000);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
|
||||
@@ -135,7 +135,7 @@ public class Kperf implements Runnable{
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试3/4:上传带宽测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=60000;
|
||||
testPacket=new TESTNPacket(60000);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
|
||||
@@ -146,7 +146,7 @@ public class Kperf implements Runnable{
|
||||
}else {
|
||||
System.out.println("测试3/4:下载带宽测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=60000;
|
||||
testPacket=new TESTNPacket(60000);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
|
||||
@@ -162,7 +162,7 @@ public class Kperf implements Runnable{
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试2/4:下载包转发率测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=0;
|
||||
testPacket=new TEST1Packet();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
|
||||
@@ -171,7 +171,7 @@ public class Kperf implements Runnable{
|
||||
}else {
|
||||
System.out.println("测试2/4:上传包转发率测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=0;
|
||||
testPacket=new TEST1Packet();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
|
||||
@@ -186,7 +186,7 @@ public class Kperf implements Runnable{
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试3/4:上传包转发率测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=0;
|
||||
testPacket=new TEST1Packet();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
|
||||
@@ -196,7 +196,7 @@ public class Kperf implements Runnable{
|
||||
}else {
|
||||
System.out.println("测试3/4:下载包转发率测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=0;
|
||||
testPacket=new TEST1Packet();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
|
||||
@@ -206,17 +206,19 @@ public class Kperf implements Runnable{
|
||||
}
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
|
||||
System.out.println("测速结束!");
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("测速结束!");
|
||||
System.out.println("测速被中断!");
|
||||
}finally {
|
||||
close();
|
||||
}
|
||||
});
|
||||
try {
|
||||
monitor.setState(MonitorData.CONNECTING);
|
||||
if(link==null)
|
||||
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000);
|
||||
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000);
|
||||
|
||||
|
||||
link.setSoTimeout(20000);
|
||||
@@ -243,10 +245,9 @@ public class Kperf implements Runnable{
|
||||
|
||||
}else {
|
||||
|
||||
|
||||
if (test.checkTransmit(testSize+3)) {
|
||||
TESTPacket tp=new TESTPacket(testSize);
|
||||
writePacketToKPL(tp);
|
||||
KLALBPacket testp=testPacket;
|
||||
if (testp!=null&&test.checkTransmit(testp.getLength())) {
|
||||
writePacketToKPL(testp);
|
||||
|
||||
|
||||
|
||||
@@ -351,7 +352,7 @@ public class Kperf implements Runnable{
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
|
||||
// System.out.println(congressSpeed);
|
||||
break;
|
||||
case KLALBPacket.TEST:
|
||||
case KLALBPacket.TESTN:
|
||||
break;
|
||||
}
|
||||
Thread.yield();
|
||||
@@ -371,6 +372,7 @@ public class Kperf implements Runnable{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
tc.interrupt();
|
||||
}
|
||||
}
|
||||
private volatile long time = System.nanoTime();
|
||||
@@ -441,7 +443,7 @@ public class Kperf implements Runnable{
|
||||
|
||||
|
||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = link.readPacket();
|
||||
KLALBPacket packet = link.readKLALBPacket();
|
||||
if (showpacket) {
|
||||
|
||||
System.out.println("RX:" + packet);
|
||||
@@ -459,7 +461,7 @@ public class Kperf implements Runnable{
|
||||
long length=packet.getLength();
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
link.writePacket(packet);
|
||||
link.writeKLALBPacket(packet);
|
||||
link.flush();
|
||||
packet.putTimePassport("sended");
|
||||
packet.printPassport();
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.kne.cloud.network.perf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
|
||||
public class MemcpyBenchmark {
|
||||
public static void testArrayCopySpeed(int i) {
|
||||
byte[]a=new byte[i];
|
||||
byte[]b=new byte[i];
|
||||
long start=System.nanoTime();
|
||||
System.arraycopy(a, 0, b, 0, i);
|
||||
long time=System.nanoTime()-start;
|
||||
long speed=i*1000000000L/time;
|
||||
System.out.println(speed/1024L/1024L+" MB/s");
|
||||
}
|
||||
public static void testByteBufferCopySpeed(int i) {
|
||||
ByteBuffer a=ByteBuffer.allocateDirect(i);
|
||||
ByteBuffer b=ByteBuffer.allocateDirect(i);
|
||||
long start=System.nanoTime();
|
||||
a.put(b);
|
||||
long time=System.nanoTime()-start;
|
||||
long speed=i*1000000000L/time;
|
||||
System.out.println(speed/1024L/1024L+" MB/s");
|
||||
}
|
||||
public static Object un;
|
||||
public static void testDirectByteBufferAllocateSpeed(int i) {
|
||||
long start=System.nanoTime();
|
||||
for(int ix=0;ix<10000;ix++) {
|
||||
ByteBuffer a=ByteBuffer.allocateDirect(i);
|
||||
un=a;
|
||||
}
|
||||
long time=System.nanoTime()-start;
|
||||
long speed=i*1000000000L/time*10000L;
|
||||
System.out.println(speed/1024L/1024L+" MB/s");
|
||||
}
|
||||
public static void testByteBufferAllocateSpeed(int i) {
|
||||
long start=System.nanoTime();
|
||||
for(int ix=0;ix<10000;ix++) {
|
||||
ByteBuffer a=ByteBuffer.allocate(i);
|
||||
un=a;
|
||||
}
|
||||
long time=System.nanoTime()-start;
|
||||
long speed=i*1000000000L/time*10000L;
|
||||
System.out.println(speed/1024L/1024L+" MB/s");
|
||||
}
|
||||
public static void testByteBufferAllocatorSpeed(int i) {
|
||||
long start=System.nanoTime();
|
||||
for(int ix=0;ix<10000;ix++) {
|
||||
ByteBuffer a=NetworkPacket.bufferAllocator.allocate(i);
|
||||
un=a;
|
||||
}
|
||||
long time=System.nanoTime()-start;
|
||||
long speed=i*1000000000L/time*10000L;
|
||||
System.out.println(speed/1024L/1024L+" MB/s");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package org.kne.cloud.network.perf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.SocketChannelListener;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.klalb.KLALBController;
|
||||
import org.kne.cloud.network.klalb.KLALBRemoteLine;
|
||||
import org.kne.cloud.network.klalb.StreamChannelKLALBPacketLink;
|
||||
|
||||
public class NodeBenchmark implements Runnable{
|
||||
private List<NodeEntry> nodeList=new ArrayList<>();
|
||||
private class NodeEntry{
|
||||
private SocketChannelListener scl;
|
||||
private KLALBController kc;
|
||||
public SocketChannelListener getScl() {
|
||||
return scl;
|
||||
}
|
||||
public KLALBController getKc() {
|
||||
return kc;
|
||||
}
|
||||
public NodeEntry(SocketChannelListener scl, KLALBController kc) {
|
||||
super();
|
||||
this.scl = scl;
|
||||
this.kc = kc;
|
||||
}
|
||||
|
||||
}
|
||||
private KLALBController klalbController;
|
||||
private int nodes;
|
||||
public NodeBenchmark(KLALBController klalbController,int nodes) {
|
||||
this.klalbController=klalbController;
|
||||
this.nodes=nodes;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Random r=new Random();
|
||||
for (int i = 0; i < nodes; i++) {
|
||||
KLALBController kct=new KLALBController(false);
|
||||
try {
|
||||
SocketChannelListener scl=new SocketChannelListener(ServerSocketChannel.open().bind(new InetSocketAddress("127.0.0.8",0)));
|
||||
scl.setCon((c)->{
|
||||
try {
|
||||
kct.addRemoteLine(new KLALBRemoteLine(new StreamChannelKLALBPacketLink(c)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
System.out.println("KLALBController "+i+" created,locator:"+kct.getSelf());
|
||||
int size=nodeList.size();
|
||||
if(size>0) {
|
||||
for (int j = 0; j < 1; j++) {
|
||||
int ind=r.nextInt(size);
|
||||
NodeEntry ne=nodeList.get(ind);
|
||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress((InetSocketAddress) ne.getScl().getServerSocketChannel().getLocalAddress());
|
||||
kct.addRemoteLines(mpsa);
|
||||
System.out.println("connect:" +ne.getKc().getSelf().getAddress());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
nodeList.add(new NodeEntry( scl, kct));
|
||||
Thread.sleep(100);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
NodeEntry ne=nodeList.get(0);
|
||||
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress((InetSocketAddress) ne.getScl().getServerSocketChannel().getLocalAddress());
|
||||
klalbController.addRemoteLines(mpsa);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void startPerfing() {
|
||||
ThreadTool.makeVThreadIfSupport("节点数量测试线程" ,this).start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.kne.cloud.network.perf;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
|
||||
public class TEST1Packet extends KLALBPacket {
|
||||
private static final int HEADER_LENGTH=1;
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
return HEADER_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
public TEST1Packet() {
|
||||
super(TEST1,HEADER_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
public TEST1Packet(ByteBuffer bb) {
|
||||
super(bb,HEADER_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TEST1";
|
||||
}
|
||||
}
|
||||
+9
-8
@@ -1,4 +1,4 @@
|
||||
package org.kne.cloud.network.klalb;
|
||||
package org.kne.cloud.network.perf;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
@@ -11,8 +11,9 @@ import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import org.kne.cloud.network.NetworkPacket;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
|
||||
public class TESTPacket extends KLALBPacket {
|
||||
public class TESTNPacket extends KLALBPacket {
|
||||
|
||||
private static final int HEADER_LENGTH=3;
|
||||
|
||||
@@ -23,8 +24,8 @@ public class TESTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
|
||||
public TESTPacket(int limit) {
|
||||
super(TEST,HEADER_LENGTH);
|
||||
public TESTNPacket(int limit) {
|
||||
super(TESTN,HEADER_LENGTH);
|
||||
//dataBuffer.limit(limit);
|
||||
dataBuffer=ByteBuffer.allocate(limit);
|
||||
}
|
||||
@@ -37,7 +38,7 @@ public class TESTPacket extends KLALBPacket {
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
klalbHeader.putChar(1, (char) dataBuffer.limit());
|
||||
super.writeToChannel(dto);
|
||||
//System.out.println(dataBuffer);
|
||||
@@ -45,7 +46,7 @@ public class TESTPacket extends KLALBPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||||
super.readFromChannel(din);
|
||||
int limit=klalbHeader.getChar(1);
|
||||
//dataBuffer.clear();
|
||||
@@ -59,14 +60,14 @@ public class TESTPacket extends KLALBPacket {
|
||||
dataBuffer.flip();
|
||||
}
|
||||
|
||||
public TESTPacket(ByteBuffer bb) {
|
||||
public TESTNPacket(ByteBuffer bb) {
|
||||
super(bb,HEADER_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TEST["+dataBuffer.limit()+"]";
|
||||
return "TESTN["+dataBuffer.limit()+"]";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kne.cloud.network.klalb.IPSequence;
|
||||
|
||||
public class ACKSEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
public ACKSEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ACKSEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
|
||||
}
|
||||
|
||||
public ACKSEQSSegmentRoutingTLV(UUID ackid, boolean promise) {
|
||||
super(IPv6SegmentRoutingTLV.ACKSEQS);
|
||||
setUUID(ackid);
|
||||
setPromise(promise);
|
||||
getData().limit(22);
|
||||
}
|
||||
public ACKSEQSSegmentRoutingTLV(IPSequence ackid, boolean promise) {
|
||||
super(IPv6SegmentRoutingTLV.ACKSEQS);
|
||||
setIPSequence(ackid);
|
||||
setPromise(promise);
|
||||
getData().limit(22);
|
||||
}
|
||||
public void setUUID(UUID uuid) {
|
||||
getData().putLong(6,uuid.getMostSignificantBits());
|
||||
getData().putLong(14,uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return new UUID(getData().getLong(6),getData().getLong(14));
|
||||
}
|
||||
public void setIPSequence(IPSequence ackid) {
|
||||
setUUID(ackid.getUuid());
|
||||
}
|
||||
|
||||
public IPSequence getIPSequence() {
|
||||
return new IPSequence(getUUID(),isPromise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.writeToChannel(dto);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
|
||||
}
|
||||
|
||||
public long getSequence() {
|
||||
return getData().getLong(6);
|
||||
}
|
||||
public void setSequence(long sequence) {
|
||||
getData().putLong(6,sequence);
|
||||
}
|
||||
public int getFlowNumber() {
|
||||
return getData().getInt(2);
|
||||
}
|
||||
public void setFlowNumber(int flowsequence) {
|
||||
getData().putInt(2,flowsequence);
|
||||
}
|
||||
public void setACKIP(Inet6Address ip) {
|
||||
getData().put(14, ip.getAddress());
|
||||
}
|
||||
public Inet6Address getACKIP() {
|
||||
byte[]arr=new byte[16];
|
||||
getData().get(14,arr);
|
||||
try {
|
||||
return (Inet6Address) Inet6Address.getByAddress(arr);
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public boolean isPromise() {
|
||||
return getData().get(0)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setPromise(boolean promise) {
|
||||
if(promise) {
|
||||
getData().put(0, (byte) 1);
|
||||
}else {
|
||||
getData().put(0, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
public interface DijkstraAlgorithm extends Runnable{
|
||||
public static final long MAX_WEIGHT=Long.MAX_VALUE/256L;
|
||||
public void setGraph(long[][]pointers,long[][]heap,long startPoint) ;
|
||||
public void run();
|
||||
public long[] getDirection();
|
||||
|
||||
@@ -14,14 +14,21 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public static final int PADN=4;
|
||||
public static final int HMAC=5;
|
||||
public static final int SEQS=7;
|
||||
public static final int ACKSEQS=8;
|
||||
|
||||
private int headerLength=2;
|
||||
|
||||
public int getHeaderLength() {
|
||||
return headerLength;
|
||||
}
|
||||
|
||||
private boolean isDefault;
|
||||
|
||||
protected volatile ByteBuffer header;
|
||||
|
||||
private ByteBuffer data;
|
||||
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
|
||||
this(header,true);
|
||||
}
|
||||
|
||||
@@ -32,7 +39,10 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
|
||||
super();
|
||||
this.header = header;
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
this.isDefault=isDefault;
|
||||
if(getType()==PAD1)
|
||||
headerLength=1;
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data=ByteBuffer.allocate(512);
|
||||
}
|
||||
}
|
||||
@@ -42,17 +52,19 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
|
||||
super();
|
||||
this.header=ByteBuffer.allocate(2);
|
||||
this.isDefault=isDefault;
|
||||
header.put((byte) type);
|
||||
if(isDefault&&(type!=PAD1)) {
|
||||
if(type==PAD1) {
|
||||
headerLength=1;
|
||||
}
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data=ByteBuffer.allocate(512);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
if(getType()==PAD1)
|
||||
return 1;
|
||||
return header.limit()+(isDefault?data.limit():0);
|
||||
return headerLength+(isDefault?data.limit():0);
|
||||
}
|
||||
|
||||
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
|
||||
@@ -74,6 +86,14 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
rtlv=new PADNSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
case SEQS:
|
||||
rtlv=new SEQSSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
case ACKSEQS:
|
||||
rtlv=new ACKSEQSSegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
return rtlv;
|
||||
default:
|
||||
rtlv=new IPv6SegmentRoutingTLV(bbf);
|
||||
rtlv.readFromChannel(din);
|
||||
@@ -84,26 +104,26 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
tlv.writeToChannel(dto);
|
||||
}
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
setDataLength(data.limit());
|
||||
}
|
||||
header.limit(headerLength);
|
||||
dto.write(header.slice(0,header.limit()));
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
dto.write(data.slice(0, data.limit()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
header.limit(1);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
int type=getType();
|
||||
if(type!=PAD1) {
|
||||
if(headerLength>1) {
|
||||
header.limit(2);
|
||||
while (header.hasRemaining()) {
|
||||
if (din.read(header) == -1) {
|
||||
@@ -113,7 +133,7 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
||||
}
|
||||
header.flip();
|
||||
|
||||
if(isDefault&&(getType()!=PAD1)) {
|
||||
if(isDefault&&(headerLength>1)) {
|
||||
data.clear();
|
||||
data.limit(getDataLength());
|
||||
while(data.hasRemaining()){
|
||||
|
||||
@@ -32,26 +32,41 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
import org.kne.cloud.network.klalb.KLALBVirtualRawSocket;
|
||||
import org.kne.cloud.network.monitor.DelayMonitorData;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
|
||||
import org.kne.cloud.network.scanner.InetAddressRange;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
|
||||
import com.google.gson.internal.Pair;
|
||||
|
||||
public class KLALBRoutingProtocol extends Thread{
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
|
||||
private RouterInfo selfRouterInfo;
|
||||
private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private volatile Map<Inet6Address,Long>addresses;
|
||||
|
||||
private volatile Map<Inet6Address, Set<LinkDirection>> paths;
|
||||
private volatile Map<Inet6Address, List<LinkDirection>> paths;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static final int DEFAULT_PORT=1001;
|
||||
|
||||
public static final int DEFAULT_PROTOCOL_NUMBER=252;
|
||||
|
||||
public static final long HOTSOPT_TIMEOUT = 1000000000;
|
||||
|
||||
public static final int HOTSOPT_REPORT_INTERVAL = 100000000;
|
||||
@@ -63,60 +78,59 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
this.router=router;
|
||||
}
|
||||
|
||||
private ReentrantLock sendlock=new ReentrantLock();
|
||||
//private ReentrantLock sendlock=new ReentrantLock();
|
||||
|
||||
private long floodTimer=System.nanoTime();
|
||||
private long floodTimer2=System.nanoTime();
|
||||
private long requestTimer=System.nanoTime();
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("KLALB路由协议接收线程");
|
||||
getSelfRouterInfo();
|
||||
DatagramSocket ds = null;
|
||||
KLALBVirtualRawSocket ds = null;
|
||||
try{
|
||||
ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) );
|
||||
DatagramSocket ds2=ds;
|
||||
ds=new KLALBVirtualRawSocket(router,router.getLocator().getAddress(), DEFAULT_PROTOCOL_NUMBER);
|
||||
KLALBVirtualRawSocket ds2=ds;
|
||||
new Thread(()->{
|
||||
Thread.currentThread().setName("KLALB路由协议接收线程");
|
||||
|
||||
while(true) {
|
||||
try {
|
||||
/*List<NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
byte[]to=createLinkStatePacket(nls);
|
||||
DatagramPacket dgp=new DatagramPacket(to,to.length);
|
||||
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
NetworkLink nl=(NetworkLink) nls[i];
|
||||
if(!nl.isLoopBack()) {
|
||||
Set<Inet6Address>neis=nl.discoverNeighbors();
|
||||
for (Iterator<Inet6Address> iteratorx = neis.iterator(); iteratorx.hasNext();) {
|
||||
Inet6Address addresses = (Inet6Address) iteratorx.next();
|
||||
dgp.setAddress(addresses);
|
||||
dgp.setPort(DEFAULT_PORT);
|
||||
ds2.send(dgp);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
RouterInfo slf= getSelfRouterInfo();
|
||||
RouterInfo oslf=netmap.put(slf.getLocator().getAddress(), slf);
|
||||
selfRouterInfo = getSelfRouterInfo();
|
||||
RouterInfo oslf=netmap.put(selfRouterInfo.getLocator().getAddress(), selfRouterInfo);
|
||||
noticeUpdate();
|
||||
if(oslf==null||(!slf.equals(oslf))) {
|
||||
//System.out.println("change:"+oslf+"\n"+slf);
|
||||
/*if(oslf==null||(!selfRouterInfo.equals(oslf))) {
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer2>5000000000L) {
|
||||
//System.out.println("update10");
|
||||
floodTimer2=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
|
||||
}
|
||||
}else {
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer>60000000000L) {
|
||||
//System.out.println("update60");
|
||||
floodTimer=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
|
||||
}
|
||||
}*/
|
||||
|
||||
long cur=System.nanoTime();
|
||||
if(cur-floodTimer>60000000000L) {
|
||||
if(debug)
|
||||
System.out.println("update60");
|
||||
floodTimer=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,-1));
|
||||
}
|
||||
Set<Inet6Address> requestSet=new HashSet<>();
|
||||
|
||||
if(cur-floodTimer2>1000000000L) {
|
||||
if(debug)
|
||||
System.out.println("update1");
|
||||
floodTimer2=cur;
|
||||
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,router.getASN()));
|
||||
}
|
||||
|
||||
//Set<Inet6Address> requestSet=new HashSet<>();
|
||||
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = netmap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next();
|
||||
RouterInfo val=type.getValue();
|
||||
@@ -124,7 +138,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
iterator.remove();
|
||||
noticeUpdate();
|
||||
}
|
||||
Set<NeighborInfo> ads=val.getNeighborAddresses();
|
||||
/*List<NeighborInfo> ads=val.getNeighborAddresses();
|
||||
for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) {
|
||||
Inet6Address address=iterator2.next().getLocator().getAddress();
|
||||
//System.out.println(address);
|
||||
@@ -132,35 +146,37 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
requestSet.add(address);
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
computeShortestPathIfUpdated();
|
||||
|
||||
|
||||
|
||||
/*long cur2=System.nanoTime();
|
||||
if(cur2-requestTimer>1000000000L) {
|
||||
requestTimer=cur2;
|
||||
|
||||
for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) {
|
||||
Inet6Address inet6Address = (Inet6Address) iterator.next();
|
||||
byte[]to=new byte[] {0};
|
||||
DatagramPacket dgp=new DatagramPacket(to,to.length);
|
||||
dgp.setAddress(inet6Address);
|
||||
dgp.setPort(DEFAULT_PORT);
|
||||
|
||||
writePacket(ds2, new RouterInfoRequestPacket( ), new InetSocketAddress(inet6Address, DEFAULT_PORT));
|
||||
|
||||
if(debug)
|
||||
System.out.println("Request:"+inet6Address);
|
||||
sendlock.lock();
|
||||
try {
|
||||
ds2.send(dgp);
|
||||
}catch(SocketException e) {
|
||||
System.out.println("Send failed:"+dgp.getAddress());
|
||||
}finally {
|
||||
sendlock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
for (Iterator<Entry<Inet6Address, HotspotAddressTimer>> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next();
|
||||
if(type.getValue().checkReportTime()) {
|
||||
//System.out.println("hotspot address:"+type.getKey());
|
||||
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
|
||||
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false,-1), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
|
||||
}
|
||||
if(type.getValue().checkTimeOut()) {
|
||||
iterator.remove();
|
||||
@@ -193,8 +209,16 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
switch(kp.getType()) {
|
||||
case KLALBRoutingProtocolPacket.RINFO_REQ:
|
||||
RouterInfo rifr=netmap.get(router.getLocator().getAddress());
|
||||
if(rifr!=null)
|
||||
writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress());
|
||||
if(debug)
|
||||
System.out.println("get Request from:"+dgp.getSocketAddress());
|
||||
if(rifr!=null) {
|
||||
writePacket(ds, new RouterInfoPacket( rifr,false,-1), dgp.getSocketAddress());
|
||||
if(debug)
|
||||
System.out.println("response router info:"+rifr);
|
||||
}else {
|
||||
if(debug)
|
||||
System.out.println("router info is null!");
|
||||
}
|
||||
break;
|
||||
case KLALBRoutingProtocolPacket.RINFO:
|
||||
|
||||
@@ -237,7 +261,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
}
|
||||
}
|
||||
|
||||
private void floodPacket(DatagramSocket ds,SocketAddress except,KLALBRoutingProtocolPacket rifp) throws IOException {
|
||||
private void floodPacket(KLALBVirtualRawSocket ds2,SocketAddress except,RouterInfoPacket rifp) throws IOException {
|
||||
long asn=rifp.getASN();
|
||||
List<IPv6NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
@@ -248,27 +273,31 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT);
|
||||
if(!isa.equals(except)) {
|
||||
writePacket(ds, rifp, isa);
|
||||
if(asn==-1) {
|
||||
writePacket(ds2, rifp, isa);
|
||||
}else{
|
||||
RouterInfo nif= netmap.get(isa.getAddress());
|
||||
if(nif!=null&&nif.getAsn()==asn) {
|
||||
writePacket(ds2, rifp, isa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writePacket(DatagramSocket ds,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
|
||||
private void writePacket(KLALBVirtualRawSocket ds2,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
|
||||
ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
|
||||
KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt);
|
||||
byte[]to=bos.toByteArray();
|
||||
DatagramPacket dgpx=new DatagramPacket(to,to.length);
|
||||
dgpx.setSocketAddress(dest);
|
||||
sendlock.lock();
|
||||
try {
|
||||
ds.send(dgpx);
|
||||
ds2.send(dgpx);
|
||||
}catch(BindException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Cannot assign:"+dest);
|
||||
}finally {
|
||||
sendlock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,47 +358,51 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
return;
|
||||
}
|
||||
Set<Entry<Inet6Address, RouterInfo>> s=netmap.entrySet();
|
||||
Map<Inet6Address,Long>airs=new HashMap<>();
|
||||
Map<Inet6Address,Long>airs=new HashMap<>(netmap.size()+1);
|
||||
|
||||
List<Inet6Address>rias=new ArrayList<>();
|
||||
List<Inet6Address>rias=new ArrayList<>(netmap.size()+1);
|
||||
|
||||
Map<Inet6Address,Set< LinkDirection>>paths=new HashMap<>();
|
||||
Map<Inet6Address,List< LinkDirection>>paths=new HashMap<>();
|
||||
long number=0;
|
||||
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = s.iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, RouterInfo> entry = (Entry<Inet6Address, RouterInfo>) iterator.next();
|
||||
for(Entry<Inet6Address, RouterInfo> entry:s) {
|
||||
if(!airs.containsKey(entry.getKey())) {
|
||||
airs.put(entry.getKey(),number);
|
||||
rias.add( entry.getKey());
|
||||
number++;
|
||||
}
|
||||
Set<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
|
||||
for (Iterator<NeighborInfo> iterator2 = ni.iterator(); iterator2.hasNext();) {
|
||||
NeighborInfo neighborInfo = (NeighborInfo) iterator2.next();
|
||||
List<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
|
||||
for(NeighborInfo neighborInfo :ni) {
|
||||
Inet6Address ias2=neighborInfo.getLocator().getAddress();
|
||||
if(!airs.containsKey(ias2)) {
|
||||
airs.put(ias2,number);
|
||||
rias.add( ias2);
|
||||
number++;
|
||||
}
|
||||
Set<LinkDirection>lp1=paths.get(entry.getKey());
|
||||
List<LinkDirection>lp1=paths.get(entry.getKey());
|
||||
if(lp1==null) {
|
||||
paths.put(entry.getKey(), lp1=new HashSet<>());
|
||||
paths.put(entry.getKey(), lp1=new ArrayList<>());
|
||||
}
|
||||
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
|
||||
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadDelayMin(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
|
||||
|
||||
Set<LinkDirection>lp2=paths.get(ias2);
|
||||
/*Set<LinkDirection>lp2=paths.get(ias2);
|
||||
if(lp2==null) {
|
||||
paths.put(ias2, lp2=new HashSet<>());
|
||||
}
|
||||
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
|
||||
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadDelayMin(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
long[][]pointers=new long[(int) airs.size()][2];
|
||||
long heappos=0;
|
||||
long linknumber=0;
|
||||
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
|
||||
for(Entry<Inet6Address, List<LinkDirection>> entry:paths.entrySet()) {
|
||||
/*for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();*/
|
||||
linknumber+=entry.getValue().size();
|
||||
}
|
||||
long[][]heap=new long[(int) (linknumber)][2];
|
||||
@@ -377,12 +410,16 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
long heapindex=0;
|
||||
pointers[(int) i][0]=heappos;
|
||||
InetAddress ia=rias.get((int) i);
|
||||
Set<LinkDirection>lks=paths.get(ia);
|
||||
List<LinkDirection>lks=paths.get(ia);
|
||||
if(lks!=null)
|
||||
for(LinkDirection linkPath:lks) {
|
||||
/*
|
||||
for (Iterator<LinkDirection> iterator = lks.iterator(); iterator.hasNext();) {
|
||||
LinkDirection linkPath=iterator.next();
|
||||
LinkDirection linkPath=iterator.next();*/
|
||||
heap[(int)(heappos+ heapindex)][0]=airs.get(linkPath.getToLocator());
|
||||
heap[(int) (heappos+heapindex)][1]=linkPath.getWeight();
|
||||
//heap[(int) (heappos+heapindex)][2]=linkPath.get
|
||||
// heap[(int) (heappos+heapindex)][3]=0;
|
||||
heapindex++;
|
||||
|
||||
}
|
||||
@@ -391,6 +428,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
pointers[(int) i][1]=heapindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress()));
|
||||
algorithm.run();
|
||||
directions=new NetmapDirections(algorithm.getDirection(), rias, airs);
|
||||
@@ -407,12 +446,12 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
private Inet6Address fromLocator;
|
||||
private Inet6Address toLocator;
|
||||
private long delay;
|
||||
private long delayMin;
|
||||
private long speed;
|
||||
public long getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
private long bandwidth;
|
||||
private long usedBandwidth=0;
|
||||
public Inet6AddressGroup getFromAddress() {
|
||||
return fromAddress;
|
||||
}
|
||||
@@ -425,22 +464,28 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
public long getBandwidth() {
|
||||
return bandwidth;
|
||||
}
|
||||
|
||||
public long getDelayMin() {
|
||||
return delayMin;
|
||||
}
|
||||
|
||||
public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator,
|
||||
Inet6Address toLocator,long delay,long speed, long bandwidth) {
|
||||
Inet6Address toLocator, long delay, long delayMin, long speed, long bandwidth) {
|
||||
super();
|
||||
this.fromAddress = fromAddress;
|
||||
this.toAddress = toAddress;
|
||||
this.fromLocator = fromLocator;
|
||||
this.toLocator = toLocator;
|
||||
this.delay = delay;
|
||||
this.speed=speed;
|
||||
this.delayMin = delayMin;
|
||||
this.speed = speed;
|
||||
this.bandwidth = bandwidth;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator="
|
||||
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed
|
||||
+ ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]";
|
||||
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", delayMin=" + delayMin
|
||||
+ ", speed=" + speed + ", bandwidth=" + bandwidth + "]";
|
||||
}
|
||||
public Inet6Address getFromLocator() {
|
||||
return fromLocator;
|
||||
@@ -470,8 +515,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
private RouterInfo getSelfRouterInfo() {
|
||||
List<IPv6NetworkLink>links=router.getLinkTabel();
|
||||
Object[] nls=links.toArray();
|
||||
RouterInfo ri=new RouterInfo(System.currentTimeMillis());
|
||||
ri.setLocator(router.getLocator());
|
||||
RouterInfo ri=new RouterInfo(System.currentTimeMillis(),router.getLocator(),router.getASN());
|
||||
for(int i=0;i<nls.length;i++) {
|
||||
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
|
||||
if((!nl.isLoopBack())&&nl.isUp()) {
|
||||
@@ -480,6 +524,8 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
Neighbor addresses = (Neighbor) iteratorx.next();
|
||||
long updelay=10000000000L;
|
||||
long downdelay=10000000000L;
|
||||
long updelayMin=10000000000L;
|
||||
long downdelayMin=10000000000L;
|
||||
long uploadspeed=1024L*1024;
|
||||
long downloadspeed=1024L*1024;
|
||||
long uploadspeedmax=1024L*1024;
|
||||
@@ -489,6 +535,11 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
if(md instanceof DelayMonitorData) {
|
||||
updelay=((DelayMonitorData) md).getOutDelay();
|
||||
downdelay=((DelayMonitorData) md).getInDelay();
|
||||
|
||||
if(md instanceof SpeedAndTrafficAndDelayMonitorDataImpl) {
|
||||
updelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getOutDelayMin();
|
||||
downdelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getInDelayMin();
|
||||
}
|
||||
}
|
||||
if(md instanceof SpeedAndTrafficMonitorData) {
|
||||
uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed();
|
||||
@@ -500,7 +551,9 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
}
|
||||
}
|
||||
}
|
||||
ri.getNeighborAddresses().add(new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax));
|
||||
NeighborInfo ni=new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay,updelayMin ,downdelayMin ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax);
|
||||
ni.setContext(addresses);
|
||||
ri.getNeighborAddresses().add(ni);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -513,7 +566,7 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
public Map<Inet6Address, Long> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
public Map<Inet6Address, Set<LinkDirection>> getPaths() {
|
||||
public Map<Inet6Address, List<LinkDirection>> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
public List<Inet6Address> createSegmentList(Inet6Address dest) {
|
||||
@@ -564,12 +617,41 @@ public class KLALBRoutingProtocol extends Thread{
|
||||
|
||||
private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>();
|
||||
public void putHotspotAddress(Inet6Address sourceAddress) {
|
||||
if(true) {
|
||||
HotspotAddressTimer hat=hotspots.get(sourceAddress);
|
||||
if(hat==null) {
|
||||
hotspots.put(sourceAddress, new HotspotAddressTimer());
|
||||
}else {
|
||||
hat.refreshTimeout();
|
||||
}
|
||||
}
|
||||
}
|
||||
private Map<Inet6Address,Long> toIpBandwidth=new ConcurrentHashMap<Inet6Address,Long>();
|
||||
|
||||
public void updateTotalRequestBandwidth(Inet6Address targetaAddress, Long treq) {
|
||||
Objects.requireNonNull(targetaAddress);
|
||||
//System.out.println("到"+targetaAddress.getHostAddress()+"请求带宽更新:"+treq);
|
||||
if(treq<=0) {
|
||||
if(toIpBandwidth.remove(targetaAddress)!=null) {
|
||||
noticeUpdate();
|
||||
}
|
||||
}else {
|
||||
Long old=toIpBandwidth.put(targetaAddress, treq);
|
||||
if(old==null||old.longValue()!=treq.longValue()) {
|
||||
noticeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Inet6Address getDijkstraPrevNode(Inet6Address text) {
|
||||
NetmapDirections directionsx=directions;
|
||||
if(directionsx==null)
|
||||
return null;
|
||||
long number= directionsx.getDirection_airs().get(text);
|
||||
long prev= directionsx.getDirection()[(int)number];
|
||||
if(prev==-1) {
|
||||
return null;
|
||||
}
|
||||
return directionsx.getDirection_rias().get((int) prev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
public KLALBRoutingProtocolPacket(int type) {
|
||||
super();
|
||||
header=NetworkPacket.databufferpool_40.borrow();
|
||||
header=NetworkPacket.bufferAllocator.allocate(40);
|
||||
header.put((byte) type);
|
||||
}
|
||||
@Override
|
||||
@@ -49,7 +49,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
|
||||
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
sndtime=System.nanoTime();
|
||||
dto.write(header.slice(0, (int) getHeaderSize()));
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
|
||||
rcvtime=System.nanoTime();
|
||||
//System.out.println(this+" "+getHeaderSize());
|
||||
header.limit((int) getHeaderSize());
|
||||
@@ -89,12 +89,6 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
/* ByteBuffer headerx=header;
|
||||
header=null;
|
||||
KLALBRoutingProtocolPacket.databufferpool_40.back(headerx);*/
|
||||
}
|
||||
|
||||
public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
|
||||
return readKLALBPacketFromChannel(Channels.newChannel(in));
|
||||
@@ -102,7 +96,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
|
||||
|
||||
public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
|
||||
while(true) {
|
||||
ByteBuffer bb=databufferpool_40.borrow();
|
||||
ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
|
||||
bb.limit(1);
|
||||
while(bb.hasRemaining()){
|
||||
if(in.read(bb)==-1) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.net.Inet6Address;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.ipv6.Neighbor;
|
||||
|
||||
public class NeighborInfo implements Serializable {
|
||||
@Override
|
||||
@@ -26,13 +27,16 @@ public class NeighborInfo implements Serializable {
|
||||
private Inet6AddressGroup local;
|
||||
private Inet6AddressGroup neighbor;
|
||||
private Inet6AddressGroup locator;
|
||||
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
|
||||
private transient Neighbor context;
|
||||
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay,long uploadDelayMin, long downloadDelayMin, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
|
||||
super();
|
||||
this.local=local;
|
||||
this.neighbor = neighbor;
|
||||
this.locator=locator;
|
||||
this.uploadDelay = uploadDelay;
|
||||
this.downloadDelay = downloadDelay;
|
||||
this.uploadDelayMin = uploadDelayMin;
|
||||
this.downloadDelayMin= downloadDelayMin;
|
||||
this.uploadSpeed = uploadSpeed;
|
||||
this.downloadSpeed = downloadSpeed;
|
||||
this.uploadSpeedMax=uploadspeedmax;
|
||||
@@ -40,12 +44,24 @@ public class NeighborInfo implements Serializable {
|
||||
}
|
||||
public NeighborInfo() {
|
||||
}
|
||||
|
||||
private long uploadDelay;
|
||||
private long downloadDelay;
|
||||
private long uploadDelayMin;
|
||||
private long downloadDelayMin;
|
||||
private long uploadSpeed;
|
||||
private long downloadSpeed;
|
||||
private long uploadSpeedMax;
|
||||
private long downloadSpeedMax;
|
||||
|
||||
|
||||
|
||||
public void setContext(Neighbor context) {
|
||||
this.context = context;
|
||||
}
|
||||
public Neighbor getContext() {
|
||||
return context;
|
||||
}
|
||||
public Inet6AddressGroup getNeighbor() {
|
||||
return neighbor;
|
||||
}
|
||||
@@ -100,6 +116,7 @@ public class NeighborInfo implements Serializable {
|
||||
public void setLocator(Inet6AddressGroup locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(local, locator, neighbor);
|
||||
@@ -122,6 +139,8 @@ public class NeighborInfo implements Serializable {
|
||||
locator.writeToStream(out);
|
||||
out.writeLong(uploadDelay);
|
||||
out.writeLong(downloadDelay);
|
||||
out.writeLong(uploadDelayMin);
|
||||
out.writeLong(downloadDelayMin);
|
||||
out.writeLong(uploadSpeed);
|
||||
out.writeLong(downloadSpeed);
|
||||
out.writeLong(uploadSpeedMax);
|
||||
@@ -134,9 +153,17 @@ public class NeighborInfo implements Serializable {
|
||||
locator=new Inet6AddressGroup(in);
|
||||
uploadDelay=in.readLong();
|
||||
downloadDelay=in.readLong();
|
||||
uploadDelayMin=in.readLong();
|
||||
downloadDelayMin=in.readLong();
|
||||
uploadSpeed=in.readLong();
|
||||
downloadSpeed=in.readLong();
|
||||
uploadSpeedMax=in.readLong();
|
||||
downloadSpeedMax=in.readLong();
|
||||
}
|
||||
public long getUploadDelayMin() {
|
||||
return uploadDelayMin;
|
||||
}
|
||||
public long getDownloadDelayMin() {
|
||||
return downloadDelayMin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
|
||||
public PAD1SegmentRoutingTLV(int type) {
|
||||
super(type);
|
||||
public PAD1SegmentRoutingTLV() {
|
||||
super(IPv6SegmentRoutingTLV.PAD1);
|
||||
}
|
||||
|
||||
public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
|
||||
@@ -11,19 +11,20 @@ public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
public PADNSegmentRoutingTLV(int type) {
|
||||
super(type);
|
||||
public PADNSegmentRoutingTLV(int dataLength) {
|
||||
super(IPv6SegmentRoutingTLV.PADN);
|
||||
getData().limit(dataLength);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.writeToChannel(dto);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
|
||||
}
|
||||
|
||||
@@ -30,12 +30,20 @@ public class RouterInfo implements Serializable{
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Inet6AddressGroup locator;
|
||||
private long asn;
|
||||
public Inet6AddressGroup getLocator() {
|
||||
return locator;
|
||||
}
|
||||
public void setLocator(Inet6AddressGroup locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
public long getAsn() {
|
||||
return asn;
|
||||
}
|
||||
public void setAsn(long asn) {
|
||||
this.asn = asn;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(locator, neighborAddresses);
|
||||
@@ -51,7 +59,7 @@ public class RouterInfo implements Serializable{
|
||||
RouterInfo other = (RouterInfo) obj;
|
||||
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses);
|
||||
}
|
||||
private Set<NeighborInfo> neighborAddresses=new HashSet<>();
|
||||
private List<NeighborInfo> neighborAddresses=new ArrayList<>();
|
||||
private long createTime;
|
||||
|
||||
|
||||
@@ -59,7 +67,7 @@ public class RouterInfo implements Serializable{
|
||||
return createTime;
|
||||
}
|
||||
private static final long INFO_UPDATETIME=10000000000L;
|
||||
private static final long INFO_TIMEOUT=20000000000L;
|
||||
private static final long INFO_TIMEOUT=120000000000L;
|
||||
private long putTime=System.nanoTime();
|
||||
public boolean checkUpdateTime() {
|
||||
return System.nanoTime()-putTime>INFO_UPDATETIME;
|
||||
@@ -74,21 +82,24 @@ public class RouterInfo implements Serializable{
|
||||
return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime
|
||||
+ "]";
|
||||
}
|
||||
public Set<NeighborInfo> getNeighborAddresses() {
|
||||
public List<NeighborInfo> getNeighborAddresses() {
|
||||
return neighborAddresses;
|
||||
}
|
||||
|
||||
public RouterInfo( long createTime) {
|
||||
public RouterInfo( long createTime,Inet6AddressGroup locator,long asn) {
|
||||
this.createTime = createTime;
|
||||
this.locator=locator;
|
||||
this.asn=asn;
|
||||
}
|
||||
|
||||
public RouterInfo() {
|
||||
}
|
||||
public void writeToStream(DataOutputStream out) throws IOException {
|
||||
locator.writeToStream(out);
|
||||
out.writeLong(asn);
|
||||
out.writeLong(createTime);
|
||||
out.writeInt(neighborAddresses.size());
|
||||
for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) {
|
||||
NeighborInfo neighborInfo = (NeighborInfo) iterator.next();
|
||||
for( NeighborInfo neighborInfo :neighborAddresses) {
|
||||
neighborInfo.writeToStream(out);
|
||||
}
|
||||
}
|
||||
@@ -101,9 +112,10 @@ public class RouterInfo implements Serializable{
|
||||
}
|
||||
public void readFromStream(DataInputStream in) throws IOException {
|
||||
locator=new Inet6AddressGroup(in);
|
||||
asn=in.readLong();
|
||||
createTime=in.readLong();
|
||||
int size=in.readInt();
|
||||
neighborAddresses=new HashSet<>(size);
|
||||
neighborAddresses=new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
NeighborInfo nif=new NeighborInfo();
|
||||
nif.readFromStream(in);
|
||||
|
||||
@@ -24,9 +24,10 @@ import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
|
||||
public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{
|
||||
|
||||
public RouterInfoPacket(RouterInfo routerInfo, boolean flood) {
|
||||
public RouterInfoPacket(RouterInfo routerInfo, boolean flood,long asn) {
|
||||
super(RINFO);
|
||||
getHeader().put(1,(byte) (flood?1:0));
|
||||
getHeader().putLong(2,asn);
|
||||
this.rinfo=routerInfo;
|
||||
}
|
||||
protected RouterInfoPacket(ByteBuffer bb) {
|
||||
@@ -39,12 +40,16 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
|
||||
return (getHeader().get(1)&1)==1;
|
||||
}
|
||||
|
||||
public long getASN() {
|
||||
return getHeader().getLong(2);
|
||||
}
|
||||
|
||||
public RouterInfo getRinfo() {
|
||||
return rinfo;
|
||||
}
|
||||
@Override
|
||||
protected long getHeaderSize() {
|
||||
return super.getHeaderSize()+1;
|
||||
return super.getHeaderSize()+9;
|
||||
}
|
||||
@Override
|
||||
public long getLength() {
|
||||
@@ -60,12 +65,12 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
super.writeToChannel(dto);
|
||||
rinfo.writeToChannel(dto);
|
||||
}
|
||||
@Override
|
||||
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
rinfo=new RouterInfo();
|
||||
rinfo.readFromChannel(din, length);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
|
||||
public SEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
|
||||
super(klalbHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
|
||||
}
|
||||
|
||||
public SEQSSegmentRoutingTLV(long sequence,UUID uuid, boolean promise,boolean keeporder/*,int flownumber,long flowsequence*/) {
|
||||
super(IPv6SegmentRoutingTLV.SEQS);
|
||||
setSequence(sequence);
|
||||
setUUID(uuid);
|
||||
setPromise(promise);
|
||||
setKeepOrder(keeporder);
|
||||
//setFlowNumber(flownumber);
|
||||
//setFlowSequence(flowsequence);
|
||||
//getData().limit(14);
|
||||
//getData().limit(22);
|
||||
getData().limit(30);
|
||||
}
|
||||
|
||||
public void setUUID(UUID uuid) {
|
||||
getData().putLong(14,uuid.getMostSignificantBits());
|
||||
getData().putLong(22,uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return new UUID(getData().getLong(14),getData().getLong(22));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||||
|
||||
super.writeToChannel(dto);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
super.readFromChannel(din, length);
|
||||
|
||||
}
|
||||
|
||||
public long getSequence() {
|
||||
return getData().getLong(6);
|
||||
}
|
||||
public void setSequence(long sequence) {
|
||||
getData().putLong(6,sequence);
|
||||
}
|
||||
|
||||
public int getFlowNumber() {
|
||||
return getData().getInt(2);
|
||||
}
|
||||
public void setFlowNumber(int flowsequence) {
|
||||
getData().putInt(2,flowsequence);
|
||||
}
|
||||
|
||||
/*public long getFlowSequence() {
|
||||
return getData().getLong(14);
|
||||
}
|
||||
public void setFlowSequence(long flowsequence) {
|
||||
getData().putLong(14,flowsequence);
|
||||
}*/
|
||||
|
||||
public boolean isPromise() {
|
||||
return getData().get(0)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setPromise(boolean promise) {
|
||||
if(promise) {
|
||||
getData().put(0, (byte) 1);
|
||||
}else {
|
||||
getData().put(0, (byte) 0);
|
||||
}
|
||||
}
|
||||
public boolean isKeepOrder() {
|
||||
return getData().get(1)!=0?true:false;
|
||||
}
|
||||
|
||||
public void setKeepOrder(boolean keeporder) {
|
||||
if(keeporder) {
|
||||
getData().put(1, (byte) 1);
|
||||
}else {
|
||||
getData().put(1, (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.kne.cloud.network.srv6;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
|
||||
public class SRv6PacketReorder {
|
||||
|
||||
private PacketConsumer packetConsumer;
|
||||
|
||||
public SRv6PacketReorder(PacketConsumer packetConsumer) {
|
||||
this.packetConsumer=packetConsumer;
|
||||
}
|
||||
|
||||
private long jumpTime=500000000L;
|
||||
|
||||
private Map<Long,IPv6Packet>map=new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private long orderTime=System.nanoTime();
|
||||
private AtomicLong seqptr=new AtomicLong();
|
||||
|
||||
public void put(IPv6Packet pack, long sequence) throws IOException {
|
||||
//System.out.println(pack.getFlowLabel()+" "+sequence);
|
||||
map.put(sequence,pack);
|
||||
runOrdering();
|
||||
}
|
||||
private ReentrantLock orderLock=new ReentrantLock();
|
||||
public void runOrdering() throws IOException {
|
||||
orderLock.lock();
|
||||
try {
|
||||
boolean whi=false;
|
||||
do {
|
||||
whi=false;
|
||||
|
||||
while(true) {
|
||||
IPv6Packet i6p=map.remove(seqptr.get());
|
||||
if(i6p!=null) {
|
||||
//System.out.println("Ord:"+i6p.getFlowLabel()+" "+seqptr.get());
|
||||
seqptr.getAndIncrement();
|
||||
orderTime=System.nanoTime();
|
||||
if(packetConsumer!=null) {
|
||||
packetConsumer.accept(i6p);
|
||||
}
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
long ct=System.nanoTime();
|
||||
if(ct-orderTime>jumpTime) {
|
||||
orderTime=ct;
|
||||
long l=Long.MAX_VALUE;
|
||||
for(Long ent:map.keySet()) {
|
||||
if(ent<l) {
|
||||
l=ent;
|
||||
}
|
||||
}
|
||||
seqptr.set(l);
|
||||
whi=true;
|
||||
}
|
||||
|
||||
}while(whi);
|
||||
|
||||
}finally {
|
||||
orderLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user