This commit is contained in:
Administrator
2025-04-24 10:16:38 +08:00
parent 6de65562be
commit 7267aec1fd
108 changed files with 7621 additions and 1890 deletions
+5 -2
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <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"> <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> <attributes>
<attribute name="module" value="true"/> <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-propertiesbased-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-static-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/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.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-javadoc.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-sources.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-tests.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"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -3,7 +3,7 @@
"TCPListen" : "0.0.0.0:4565", "TCPListen" : "0.0.0.0:4565",
"UDPListen" : "{UDP}0.0.0.0:4572", "UDPListen" : "{UDP}0.0.0.0:4572",
"VirtualSocketName" : "KLALB_Stream", "VirtualSocketName" : "KLALB_Stream",
"LineTable":["cn-he-plc-2.ofalias.com:4572"] "LineTable":["07f4acdef99b.ofalias.net:4572","{UDP}07f4acdef99b.ofalias.net:4572"]
}, },
{"Type":"SocketBridge" , {"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:4572", "Listen" : "0.0.0.0:4572",
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-46
View File
@@ -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&trade;
* 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 &lt; 0 || index &gt;= 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 &lt; 0 || index &gt;= 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 &lt; 0 || index &gt; 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 &lt; 0 || index &gt;= 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 &gt; 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,4 +1,4 @@
package org.kne.cloud.network.klalb; package org.kne.cloud.network;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue; 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.Flow.Subscriber;
import java.util.concurrent.locks.LockSupport; 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.DATATPacket;
import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.klalb.KLALBRemoteLine;
@@ -14,6 +14,7 @@ import java.net.NetworkInterface;
import java.net.NoRouteToHostException; import java.net.NoRouteToHostException;
import java.net.SocketException; import java.net.SocketException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@@ -31,6 +32,15 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
private List<MultipurposeSocketAddress> msas; private List<MultipurposeSocketAddress> msas;
private volatile Consumer<MultipurposeSocketAddress> con; private volatile Consumer<MultipurposeSocketAddress> con;
private long timeInterval;
public long getTimeInterval() {
return timeInterval;
}
public void setTimeInterval(long timeInterval) {
this.timeInterval = timeInterval;
}
public NetworkInterface getNinterface() { public NetworkInterface getNinterface() {
return ninterface; return ninterface;
@@ -53,13 +63,14 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
} }
public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface, 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 = new MulticastSocket(bind);
soc.joinGroup(group, ninterface); soc.joinGroup(group, ninterface);
this.bind = bind; this.bind = bind;
this.group = group; this.group = group;
this.ninterface = ninterface; this.ninterface = ninterface;
this.msas = msas; this.msas = msas;
this.timeInterval=timeInterval;
} }
@Override @Override
@@ -104,7 +115,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
} }
Thread.sleep(10000L); Thread.sleep(timeInterval);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -133,11 +144,13 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
dis.close(); dis.close();
MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(), MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(),
port); port);
try {
InetAddress mpsai=mpsa.getInetAddress();
//System.out.println(mpsa); //System.out.println(mpsa);
Enumeration<InetAddress> ei = ninterface.getInetAddresses(); Enumeration<InetAddress> ei = ninterface.getInetAddresses();
while (ei.hasMoreElements()) { while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement(); InetAddress inetAddress = (InetAddress) ei.nextElement();
if (inetAddress.equals(mpsa.getInetAddress())) { if (inetAddress.equals(mpsai)) {
continue loop; continue loop;
} }
} }
@@ -145,13 +158,16 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
if (con != null) { if (con != null) {
con.accept(mpsa); con.accept(mpsa);
} }
}catch(UnknownHostException e) {
}
} }
} catch (IOException e) { } catch (IOException e) {
System.out.println(bind + " " + group + " " + ninterface); System.out.println(bind + " " + group + " " + ninterface);
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
try { try {
close(); close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
+14 -57
View File
@@ -7,85 +7,50 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; 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.cloud.network.klalb.KLALBPacket;
import org.kne.debug.TimeDebugger; import org.kne.debug.TimeDebugger;
public abstract class NetworkPacket implements Comparable<NetworkPacket>{ public abstract class NetworkPacket implements Comparable<NetworkPacket>{
private static final boolean debugPassport=false; 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) { if(debugPassport) {
passport=new TimeDebugger(); passport=new TimeDebugger();
passport.putTime(getClass().getSimpleName()+ "_create"); passport.putTime(getClass().getSimpleName()+ "_create");
}else {
passport=null;
} }
} }
public void putTimePassport(String label) { public final void putTimePassport(String label) {
if(passport!=null) { if(passport!=null) {
passport.putTime(label); passport.putTime(label);
} }
} }
public void printPassport() { public final void printPassport() {
if(passport!=null) { if(passport!=null) {
passport.printWithTimeFilter(100000000L); 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 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() { public long getPriority() {
return priority; 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() { public void genseq() {
this.sendseq=seqgen.getAndIncrement(); this.sendseq=seqgen.getAndIncrement();
} }
protected abstract void writeToChannel(WritableByteChannel dto) throws IOException ; public abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
protected abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException; public abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
protected void readFromChannel(ReadableByteChannel din) throws IOException{ public void readFromChannel(ReadableByteChannel din) throws IOException{
readFromChannel(din,-1); readFromChannel(din,-1);
} }
protected abstract boolean needEndPosition(); protected abstract boolean needEndPosition();
+34 -13
View File
@@ -2,6 +2,7 @@ package org.kne.cloud.network;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@@ -11,14 +12,13 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.kne.cloud.network.klalb.ByteBufferPool; public class PacketRebuilder implements ReadableByteChannel{
public class PacketRebuilder {
private static final ByteBufferPool bbfp=new ByteBufferPool(100, 65535); private static final ByteBufferPool bbfp=new ByteBufferPool(100, 65535);
private long timeout; private long timeout;
public PacketRebuilder(long timeout) { public PacketRebuilder(ReadableByteChannel readableChannel,long timeout) {
this.timeout=timeout; this.timeout=timeout;
this.readableChannel=readableChannel;
} }
@Override @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(); ByteBuffer cac=bbfp.borrow();
rc.read(cac); readableChannel.read(cac);
cac.flip(); cac.flip();
int ser=cac.getInt(0); int ser=cac.getInt(0);
int countofpiece=cac.get(4); int countofpiece=cac.get(4);
@@ -75,12 +83,12 @@ public class PacketRebuilder {
ReceiveEntry reet=recvc.get(ser); ReceiveEntry reet=recvc.get(ser);
reet.getByteBuffers()[i]=cac; reet.getByteBuffers()[i]=cac;
if(reet.isFull()) { if(reet.isFull()) {
rebuild(des ,reet.getByteBuffers()); int rez= rebuild(des ,reet.getByteBuffers());
for (int j = 0; j < reet.getByteBuffers().length; j++) { for (int j = 0; j < reet.getByteBuffers().length; j++) {
bbfp.back(reet.getByteBuffers()[j]); bbfp.back(reet.getByteBuffers()[j]);
} }
recvc.remove(ser); recvc.remove(ser);
return ; return rez;
} }
for (Iterator<Entry<Integer, ReceiveEntry>> iterator = recvc.entrySet().iterator(); iterator.hasNext();) { for (Iterator<Entry<Integer, ReceiveEntry>> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
Entry<Integer, ReceiveEntry> type = (Entry<Integer, ReceiveEntry>) iterator.next(); 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) { public int rebuild(ByteBuffer des, ByteBuffer[]src) {
//System.out.print("Rebuild:"); //StringBuilder sbd=new StringBuilder("Rebuild:");
int oldpos=des.position();
for (int i = 0; i < src.length; i++) { for (int i = 0; i < src.length; i++) {
src[i].getInt(); src[i].getInt();
src[i].get(); src[i].get();
src[i].get(); src[i].get();
des.put(src[i]); 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();
} }
+22 -15
View File
@@ -6,14 +6,12 @@ import java.nio.channels.WritableByteChannel;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.kne.cloud.network.klalb.ByteBufferPool;
public class PacketSpliter { public class PacketSpliter {
private int splitSize; private volatile int splitSize;
private static final ByteBufferPool bbfp=new ByteBufferPool(100,65535,false);
private AtomicInteger series=new AtomicInteger(); private AtomicInteger series=new AtomicInteger();
private WritableByteChannel writableChannel;
public PacketSpliter(int splitSize) { public PacketSpliter(WritableByteChannel writableChannel,int splitSize) {
this.writableChannel=writableChannel;
this.splitSize=splitSize; this.splitSize=splitSize;
} }
@@ -21,28 +19,37 @@ public class PacketSpliter {
return splitSize; return splitSize;
} }
public WritableByteChannel getWritableChannel() {
return writableChannel;
}
public void setSplitSize(int splitSize) {
this.splitSize = splitSize;
}
@Override @Override
public String toString() { public String toString() {
return "PacketSpliter [splitSize=" + splitSize + "]"; return "PacketSpliter [splitSize=" + splitSize + "]";
} }
public void write(ByteBuffer bb,WritableByteChannel wc) throws IOException{ public void write(ByteBuffer bb) throws IOException{
ByteBuffer[]bbssp= split(bb); ByteBuffer[]bbssp= split(bb);
for (int i = 0; i < bbssp.length; i++) { for (int i = 0; i < bbssp.length; i++) {
wc.write(bbssp[i]); writableChannel.write(bbssp[i]);
bbfp.back(bbssp[i]);
} }
} }
public ByteBuffer[] split(ByteBuffer bb) { public ByteBuffer[] split(ByteBuffer bb) {
//System.out.print("Split:"); //StringBuilder sbd=new StringBuilder("Split:");
int splitSizex=splitSize;
int lenth=bb.limit(); int lenth=bb.limit();
int countofpiece=(lenth-1)/splitSize+1; int countofpiece=(lenth-1)/splitSizex+1;
int remain=lenth%splitSize; int remain=lenth%splitSizex;
ByteBuffer[]pieces=new ByteBuffer[countofpiece]; ByteBuffer[]pieces=new ByteBuffer[countofpiece];
for (int i = 0; i < pieces.length; i++) { for (int i = 0; i < pieces.length; i++) {
pieces[i]=bbfp.borrow(); pieces[i]=NetworkPacket.bufferAllocator.allocate(splitSizex+6);
} }
int sern=series.getAndIncrement(); int sern=series.getAndIncrement();
for (int i = 0; i < pieces.length; i++) { 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()); bb.limit(Math.min(bb.remaining(), pieces[i].remaining())+bb.position());
pieces[i].put(bb); pieces[i].put(bb);
bb.limit(bbl); bb.limit(bbl);
//System.out.print(pieces[i].position()+" "); //sbd.append(pieces[i].position()+" ");
pieces[i].flip(); pieces[i].flip();
} }
//System.out.println(); //System.out.println(sbd);
return pieces; return pieces;
} }
+435
View File
@@ -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){ while(flag){
try { try {
SocketChannel soce=serverSocketChannel.accept(); SocketChannel soce=serverSocketChannel.accept();
ThreadTool.makePThreadIfSupport("端口监听线程",()->{ ThreadTool.makePThreadIfSupport("端口请求处理线程",()->{
if(con!=null) { if(con!=null) {
try { try {
con.accept(soce); con.accept(soce);
@@ -71,7 +71,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{
if(serverSocketChannel==null) { if(serverSocketChannel==null) {
throw new IOException(multipurposeSocketAddress.getType()+" unsupport SocketChannel"); throw new IOException(multipurposeSocketAddress.getType()+" unsupport SocketChannel");
} }
new Thread(r).start(); ThreadTool.makeVThread("端口监听线程", r).start();
} }
public void close() { public void close() {
flag=false; flag=false;
@@ -63,6 +63,7 @@ public class SpeedLimiter {
waitingtime.addAndGet(datasize*1000000000L/limitspeedx); waitingtime.addAndGet(datasize*1000000000L/limitspeedx);
} }
} }
//用系统计时器的时刻相减得到经过的时间,与数据包除以限速值得到的应消耗的时间做对比,若时间还未到达发送下一个数据包的时机,则返回false
public boolean checkTransmit(long datasize) { public boolean checkTransmit(long datasize) {
long limitspeedx=limitspeed; long limitspeedx=limitspeed;
if(limitspeedx<=0) { if(limitspeedx<=0) {
+44 -1
View File
@@ -3,8 +3,8 @@ package org.kne.cloud.network;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public class ThreadTool { public class ThreadTool {
public static boolean first=true;
public static boolean forceD=true; public static boolean forceD=true;
public static boolean first=true;
public static Thread makeVThreadIfSupport(String name,Runnable r) { public static Thread makeVThreadIfSupport(String name,Runnable r) {
if(forceD) if(forceD)
return new Thread(r, name); return new Thread(r, name);
@@ -64,4 +64,47 @@ public class ThreadTool {
rt.setDaemon(true); rt.setDaemon(true);
return rt; 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 boolean isLoopBack();
public Inet6AddressGroup getAddressGroup(); public Inet6AddressGroup getAddressGroup();
public List<Neighbor> getNeighborsInfo(); public List<Neighbor> getNeighborsInfo();
public List<RouteItem> getRouteItems();
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException; 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 String getName();
public boolean isUp(); public boolean isUp();
public boolean canSend(IPv6Packet iPv6Packet); public boolean canSend(IPv6Packet iPv6Packet);
public void setReceiveConsumer(Consumer<IPv6Packet>con); public void setReceiveConsumer(Consumer<IPv6Packet>con);
void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer);
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet);
} }
+135 -93
View File
@@ -2,6 +2,7 @@ package org.kne.cloud.network.ipv6;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.StreamCorruptedException;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@@ -11,9 +12,12 @@ import java.nio.channels.WritableByteChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; 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.NetworkPacket;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader; 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.klalb.KLALBPacket;
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV; import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
import org.kne.cloud.network.srv6.IpV6RoutingSRHData; import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
@@ -24,6 +28,29 @@ import org.kne.cloud.network.srv6.SRv6TLV;
import org.pcap4j.packet.namednumber.IpNumber; import org.pcap4j.packet.namednumber.IpNumber;
public class IPv6Packet extends NetworkPacket { 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 ByteBuffer IPv6header ;
private volatile List<IPv6ExtHeader> headers = new ArrayList<>(); private volatile List<IPv6ExtHeader> headers = new ArrayList<>();
@@ -41,7 +68,7 @@ public class IPv6Packet extends NetworkPacket {
} }
public IPv6Packet() { public IPv6Packet() {
IPv6header = NetworkPacket.databufferpool_40.borrow(); IPv6header = NetworkPacket.bufferAllocator.allocate(40);
IPv6header.limit(IPv6_HEADER_LENGTH); IPv6header.limit(IPv6_HEADER_LENGTH);
} }
@@ -76,6 +103,7 @@ public class IPv6Packet extends NetworkPacket {
public void markCE() { public void markCE() {
IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000)); IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000));
//new Exception().printStackTrace();
} }
public boolean isCE() { public boolean isCE() {
@@ -114,7 +142,24 @@ public class IPv6Packet extends NetworkPacket {
public void setHopLimit(int hopLimit) { public void setHopLimit(int hopLimit) {
IPv6header.put(7, (byte) 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() { public Inet6Address getSourceAddress() {
byte[] b = new byte[16]; byte[] b = new byte[16];
IPv6header.get(8, b, 0, b.length); IPv6header.get(8, b, 0, b.length);
@@ -163,29 +208,6 @@ public class IPv6Packet extends NetworkPacket {
return calcPayloadLength()+IPv6_HEADER_LENGTH; 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 @Override
@@ -241,7 +263,7 @@ public class IPv6Packet extends NetworkPacket {
headers.add(ext); headers.add(ext);
break; break;
case 43: case 43:
ByteBuffer bbf=NetworkPacket.databufferpool_2048.borrow(); ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(2048);
bbf.limit(4); bbf.limit(4);
while (bbf.hasRemaining()) { while (bbf.hasRemaining()) {
if (din.read(bbf) == -1) { if (din.read(bbf) == -1) {
@@ -296,7 +318,11 @@ public class IPv6Packet extends NetworkPacket {
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din); KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din);
this.payload=kp; this.payload=kp;
break loop; break loop;
case 253:
IPv6Payload epld=new IPv6EmptyPayload();
epld.readFromChannel(din, payloadlength);
this.payload=epld;
break loop;
default: default:
IPv6Payload pld=new IPv6Payload(nextheader); IPv6Payload pld=new IPv6Payload(nextheader);
pld.readFromChannel(din, payloadlength); pld.readFromChannel(din, payloadlength);
@@ -376,35 +402,7 @@ public class IPv6Packet extends NetworkPacket {
//System.out.println(payload); //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 @Override
public String toString() { public String toString() {
@@ -434,7 +432,7 @@ public class IPv6Packet extends NetworkPacket {
this.protocolNumber = protocolNumber; this.protocolNumber = protocolNumber;
this.onDefault=isonDefault; this.onDefault=isonDefault;
if(onDefault) if(onDefault)
this.data=NetworkPacket.databufferpool_65535.borrow(); this.data=NetworkPacket.bufferAllocator.allocate(65535);
} }
public int getProtocolNumber() { public int getProtocolNumber() {
@@ -446,13 +444,13 @@ public class IPv6Packet extends NetworkPacket {
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
if(onDefault) if(onDefault)
dto.write(data.slice(0,data.limit())); dto.write(data.slice(0,data.limit()));
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
if(onDefault) { if(onDefault) {
data.limit((int) length); data.limit((int) length);
while (data.hasRemaining()) { 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 @Override
protected boolean needEndPosition() { 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{ public static class IPv6ExtHeader extends NetworkPacket{
private ByteBuffer data ; private ByteBuffer data ;
@@ -505,9 +517,9 @@ public class IPv6Packet extends NetworkPacket {
this.protocolNumber = protocolNumber; this.protocolNumber = protocolNumber;
this.onDefault=isonDefault; this.onDefault=isonDefault;
if(onDefault) { if(onDefault) {
this.data=NetworkPacket.databufferpool_2048.borrow(); this.data=NetworkPacket.bufferAllocator.allocate(2048);
}else { }else {
this.data=NetworkPacket.databufferpool_40.borrow(); this.data=NetworkPacket.bufferAllocator.allocate(8);
} }
} }
@@ -542,7 +554,7 @@ public class IPv6Packet extends NetworkPacket {
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
if(onDefault) { if(onDefault) {
int ext=(data.limit()-8)/8; int ext=(data.limit()-8)/8;
setExtLength(ext); setExtLength(ext);
@@ -553,7 +565,7 @@ public class IPv6Packet extends NetworkPacket {
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
data.limit(8); data.limit(8);
while (data.hasRemaining()) { while (data.hasRemaining()) {
if (din.read(data) == -1) { if (din.read(data) == -1) {
@@ -576,19 +588,7 @@ public class IPv6Packet extends NetworkPacket {
return false; 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() { public List<Inet6Address> getAddresses() {
return addresses; return addresses;
} }
public List<IPv6SegmentRoutingTLV> getTlvs() {
return tlvs;
}
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
setExtLength(calcExtLength()/8); int exl=calcExtLength();
if(exl%8!=0) {
throw new StreamCorruptedException("extLength % 8 !=0");
}
setExtLength(exl/8);
setLastEntry(addresses.size()-1); setLastEntry(addresses.size()-1);
super.writeToChannel(dto); 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())); dto.write(ByteBuffer.wrap(inet6Address.getAddress()));
} }
for(IPv6SegmentRoutingTLV tlv:tlvs) {
IPv6SegmentRoutingTLV.writeIPv6SegmentRoutingTLVToChannel(dto, tlv);
}
} }
private int calcExtLength() { private int calcExtLength() {
int tlvsl=0; int tlvsl=0;
for (Iterator<IPv6SegmentRoutingTLV> iterator = tlvs.iterator(); iterator.hasNext();) { for(IPv6SegmentRoutingTLV tlve:tlvs) {
IPv6SegmentRoutingTLV tlve = (IPv6SegmentRoutingTLV) iterator.next();
tlvsl+=tlve.getLength(); tlvsl+=tlve.getLength();
} }
return addresses.size()*16+tlvsl; return addresses.size()*16+tlvsl;
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length); super.readFromChannel(din, length);
int extl=getExtLength(); int extl=getExtLength();
int laste=getLastEntry(); int laste=getLastEntry();
@@ -722,6 +732,13 @@ public class IPv6Packet extends NetworkPacket {
//System.out.println("SR:"+addr); //System.out.println("SR:"+addr);
addresses.add(addr); addresses.add(addr);
} }
tlvs.clear();
while(usdl<rl) {
IPv6SegmentRoutingTLV tlv=IPv6SegmentRoutingTLV.readIPv6SegmentRoutingTLVFromChannel(din);
usdl+=tlv.getLength();
tlvs.add(tlv);
}
return; return;
} }
@Override @Override
@@ -761,7 +778,20 @@ public class IPv6Packet extends NetworkPacket {
public List<IPv6ExtHeader> getHeaders() { public List<IPv6ExtHeader> getHeaders() {
return headers; 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) { /*public IPv6DestinationHeader insertDestinationHeader(int index,int extLength) {
long ptr; long ptr;
long lth=extLength*8+8; long lth=extLength*8+8;
@@ -831,6 +861,18 @@ public class IPv6Packet extends NetworkPacket {
protected boolean needEndPosition() { protected boolean needEndPosition() {
return false; 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.Closeable;
import java.io.IOException; import java.io.IOException;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@@ -19,14 +21,22 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.kne.cloud.network.NetworkPacket; 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.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; 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.IpV6RoutingSRHData;
import org.kne.cloud.network.srv6.PacketConsumer; import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.PacketReorder; 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.SRv6StreamSequenceTLV;
import org.kne.cloud.network.srv6.SRv6TLV; import org.kne.cloud.network.srv6.SRv6TLV;
import org.kne.cloud.network.srv6.TCPTransimitAgent;
import org.kne.cloud.network.tun.TUNNetworkDevice; 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.concurrent.SpinLock;
import org.kne.io.KNEChannels; import org.kne.io.KNEChannels;
@@ -42,11 +52,11 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
private Thread tr; private Thread tr;
private ThreadPoolExecutor exc = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private Lock slok=new SpinLock(); 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) if (tun != null)
throw new IllegalStateException("already open!"); throw new IllegalStateException("already open!");
try { try {
@@ -56,31 +66,42 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
this.hostAddress = hostAddress; this.hostAddress = hostAddress;
if (hostAddress != null) if (hostAddress != null)
tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength()); tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength());
if(dns!=null) {
tun.setDNSAddress(dns);
}
try {
tun.setMTU(mtu); tun.setMTU(mtu);
}catch(IOException e) {
e.printStackTrace();
}
Thread tb = new Thread(() -> { Thread tb = new Thread(() -> {
while (true) { while (true) {
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow(); ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
try { try {
tun.read(tmp); tun.read(tmp);
tmp.flip(); tmp.flip();
//System.out.println(tmp);
if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) { if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) {
while(exc.getQueue().size()>10) {
LockSupport.parkNanos(1000000); HighPerformanceExecutor.defaultExecutor.execute(() -> {
}
exc.execute(() -> {
try { try {
IPv6Packet ipp = new IPv6Packet(); IPv6Packet ipp = new IPv6Packet();
ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu); ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu);
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
if (con != null) { if (con != null) {
monitor.getOutPacketCounterAL().incrementAndGet(); monitor.getOutPacketCounterAL().incrementAndGet();
monitor.getOutTrafficAL().addAndGet(ipp.getLength()); monitor.getOutTrafficAL().addAndGet(ipp.getLength());
ipp.setDisposeAfterSend(true); // ipp.setDisposeAfterSend(true);
ipp.getPayload().setDisposeAfterSend(true); // ipp.getPayload().setDisposeAfterSend(true);
ipp.setPromise(true);
if(ipp.getPayload().getProtocolNumber()==6) {
seqm.mark(ipp);
}
con.accept(ipp); con.accept(ipp);
} else { } else {
ipp.dispose(); //ipp.dispose();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -88,10 +109,10 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
}); });
}else { }else {
NetworkPacket.databufferpool_65535.back(tmp); //NetworkPacket.databufferpool_65535.back(tmp);
} }
} catch (Exception e) { } catch (Exception e) {
NetworkPacket.databufferpool_65535.back(tmp); //NetworkPacket.databufferpool_65535.back(tmp);
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -110,9 +131,16 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
e.printStackTrace(); e.printStackTrace();
}finally { }finally {
slok.unlock(); slok.unlock();
NetworkPacket.databufferpool_65535.back(tmp); //NetworkPacket.databufferpool_65535.back(tmp);
} }
} else { } else {
for(SRv6PacketReorder spr:reorder.values()) {
try {
spr.runOrdering();
} catch (IOException e) {
e.printStackTrace();
}
}
LockSupport.parkNanos(1000000L); LockSupport.parkNanos(1000000L);
} }
@@ -132,48 +160,84 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
private SpeedAndTrafficMonitorDataImpl monitor; private SpeedAndTrafficMonitorDataImpl monitor;
private ConcurrentHashMap<FlowSession, SRv6PacketReorder> reorder=new ConcurrentHashMap<>();
@Override @Override
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException { public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
if (tun != null) {/* 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();
try { try {
// System.out.println("rev"); // System.out.println("rev");
pack.writeToChannel(KNEChannels.newWritableChannel(tmp)); IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
monitor.getInPacketCounterAL().incrementAndGet(); SEQSSegmentRoutingTLV seqs=null;
monitor.getInTrafficAL().addAndGet(pack.getLength()); if(srh!=null) {
tmp.flip(); List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
sendQueue.add(tmp);
LockSupport.unpark(tr); 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) { } catch (IOException e) {
NetworkPacket.databufferpool_65535.back(tmp); //NetworkPacket.databufferpool_65535.back(tmp);
e.printStackTrace(); e.printStackTrace();
} }
pack.disposeAll(); //pack.disposeAll();
});
} else { } 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) { private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) {
List<SRv6TLV> stv = srh.getTlvs(); List<SRv6TLV> stv = srh.getTlvs();
for (Iterator iterator = stv.iterator(); iterator.hasNext();) { for (Iterator iterator = stv.iterator(); iterator.hasNext();) {
@@ -199,8 +263,8 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
} }
@Override @Override
public boolean isCongress(IPv6Packet iPv6Packet) { public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
return sendQueue.size() > 1000; return sendQueue.size() > 1000*scale;
} }
@Override @Override
@@ -243,6 +307,36 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
return hostAddress; 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() { public int getPrefixLength() {
return prefixLength; 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) { public boolean checkMatch(Inet6Address ia) {
byte[]mask=maskTransf[prefixLength]; byte[]mask=maskTransf[prefixLength];
byte[]andj=and0(mask,ia.getAddress()); byte[]andm=getAndm(mask);
byte[]andm=and0(mask ,address.getAddress());
return Arrays.equals(andj,andm); 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]; byte[]rez=new byte[bs.length];
for (int i = 0; i < rez.length; i++) { for (int i = 0; i < rez.length; i++) {
rez[i]=(byte) (bs[i]&address2[i]); rez[i]=(byte) (bs[i]&address2[i]);
@@ -90,4 +120,5 @@ public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
address=(Inet6Address) Inet6Address.getByAddress(b); address=(Inet6Address) Inet6Address.getByAddress(b);
prefixLength=in.read(); prefixLength=in.read();
} }
} }
@@ -5,11 +5,14 @@ import java.net.InetAddress;
import java.util.Objects; import java.util.Objects;
import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
import org.kne.cloud.network.te.BandwidthDistributer;
public class Neighbor { public class Neighbor {
private Inet6AddressGroup address; private Inet6AddressGroup address;
private Inet6AddressGroup locator; private Inet6AddressGroup locator;
private MonitorData monitor; private MonitorData monitor;
private BandwidthDistributer<Inet6Address> bandwidthDistributer;
public MonitorData getMonitor() { public MonitorData getMonitor() {
return monitor; return monitor;
} }
@@ -19,12 +22,21 @@ public class Neighbor {
public Inet6AddressGroup getLocator() { public Inet6AddressGroup getLocator() {
return locator; return locator;
} }
public BandwidthDistributer<Inet6Address> getBandwidthDistributer() {
return bandwidthDistributer;
}
public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) { public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) {
super(); super();
this.address = address; this.address = address;
this.locator = locator; this.locator = locator;
this.monitor = monitor; this.monitor = monitor;
} }
public Neighbor(Inet6AddressGroup peerAddress, Inet6AddressGroup remoteVaddr, QueueingMonitorDataImpl monitor2,
BandwidthDistributer<Inet6Address> bandwidthDistributer) {
this(peerAddress,remoteVaddr,monitor2);
this.bandwidthDistributer=bandwidthDistributer;
}
@Override @Override
public String toString() { public String toString() {
return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]"; return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]";
+42 -5
View File
@@ -11,7 +11,7 @@ import org.kne.cloud.network.monitor.DelayMonitorData;
import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl; import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
public class RouteItem implements Comparable<RouteItem>{ public class RouteItem implements Comparable<RouteItem>,Cloneable{
private Inet6AddressGroup destination; private Inet6AddressGroup destination;
private Inet6Address nexthop; private Inet6Address nexthop;
private IPv6NetworkLink destlink; private IPv6NetworkLink destlink;
@@ -20,6 +20,7 @@ public class RouteItem implements Comparable<RouteItem>{
private long cost; private long cost;
private String flag; private String flag;
private MonitorData monitor; private MonitorData monitor;
private boolean isLoopback;
public String getFlag() { public String getFlag() {
return flag; return flag;
} }
@@ -44,7 +45,7 @@ public class RouteItem implements Comparable<RouteItem>{
&& pre == other.pre && Objects.equals(proto, other.proto); && pre == other.pre && Objects.equals(proto, other.proto);
} }
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre, public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
long cost,String flag) { long cost,String flag,boolean isLoopback) {
super(); super();
this.destination = destination; this.destination = destination;
this.nexthop = nexthop; this.nexthop = nexthop;
@@ -53,9 +54,10 @@ public class RouteItem implements Comparable<RouteItem>{
this.pre = pre; this.pre = pre;
this.cost = cost; this.cost = cost;
this.flag=flag; this.flag=flag;
this.isLoopback=isLoopback;
} }
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre, 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(); super();
this.destination = destination; this.destination = destination;
this.nexthop = nexthop; this.nexthop = nexthop;
@@ -65,6 +67,7 @@ public class RouteItem implements Comparable<RouteItem>{
this.cost = cost; this.cost = cost;
this.monitor=monitor; this.monitor=monitor;
this.flag=flag; this.flag=flag;
this.isLoopback=isLoopback;
} }
public Inet6AddressGroup getDestination() { public Inet6AddressGroup getDestination() {
return destination; return destination;
@@ -81,6 +84,9 @@ public class RouteItem implements Comparable<RouteItem>{
public int getPre() { public int getPre() {
return pre; return pre;
} }
public boolean isLoopback() {
return isLoopback;
}
@Override @Override
public String toString() { public String toString() {
return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop().getHostAddress()+"\t"+getDestlink().getName(); 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) { public boolean checkMatch(Inet6Address ia) {
return destination.checkMatch(ia); return destination.checkMatch(ia);
} }
public boolean checkMatch(byte[] ia) {
return destination.checkMatch(ia);
}
@Override @Override
public int compareTo(RouteItem o) { public int compareTo(RouteItem o) {
int v1=destination.compareTo(o.destination); 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))) if(monitor==null||o.monitor==null||(!(monitor instanceof DelayMonitorData))||(!(o.monitor instanceof DelayMonitorData)))
return v3; return v3;
if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl)) if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl))
return Long.compare(((DelayMonitorData)monitor).getOutDelay(), ((DelayMonitorData)o.monitor).getOutDelay()); return Long.compare(outDelay, o.outDelay);
return Long.compare(((DelayMonitorData)monitor).getOutDelay()+((QueueingMonitorDataImpl)monitor).getQueueingDelay(), ((DelayMonitorData)o.monitor).getOutDelay()+((QueueingMonitorDataImpl)o.monitor).getQueueingDelay()); 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();
}
} }
+96
View File
@@ -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 { 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); super(ACKT,HEADER_LENGTH);
klalbHeader.putInt(sport); klalbHeader.putInt(sport);
klalbHeader.putInt(dport); klalbHeader.putInt(dport);
klalbHeader.putLong(number); klalbHeader.putLong(number);
klalbHeader.put((byte) sendcount); klalbHeader.put((byte) sendcount);
klalbHeader.put((byte) (avaliable?1:0)); klalbHeader.putLong(avaliableRcvWindow);
klalbHeader.put((byte) (congress?1:0)); klalbHeader.put((byte) (congress?1:0));
klalbHeader.putLong(rcvSpeed); klalbHeader.putLong(rcvSpeed);
} }
@@ -33,7 +33,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
@Override @Override
public String toString() { public String toString() {
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable(); return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] avaliable:"+getAvaliableRcvWindow();
} }
public int getSport() { public int getSport() {
@@ -41,7 +41,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
} }
public boolean isCongress() { public boolean isCongress() {
return klalbHeader.get(19)!=0; return klalbHeader.get(26)!=0;
} }
public int getDport() { public int getDport() {
@@ -52,8 +52,8 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
return klalbHeader.getLong(9); return klalbHeader.getLong(9);
} }
public boolean isAvaliable() { public long getAvaliableRcvWindow() {
return klalbHeader.get(18)!=0; return klalbHeader.getLong(18);
} }
@@ -61,6 +61,6 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
return klalbHeader.getInt(17); return klalbHeader.getInt(17);
} }
public long getRcvSpeed() { public long getRcvSpeed() {
return klalbHeader.getLong(20); return klalbHeader.getLong(27);
} }
} }
@@ -41,7 +41,7 @@ public class ADDLINESPacket extends KLALBPacket {
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
byte[]bta=lines.getBytes(Charset.forName("UTF-8")); byte[]bta=lines.getBytes(Charset.forName("UTF-8"));
klalbHeader.putChar(1,(char) bta.length); klalbHeader.putChar(1,(char) bta.length);
super.writeToChannel(dto); super.writeToChannel(dto);
@@ -49,7 +49,7 @@ public class ADDLINESPacket extends KLALBPacket {
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din) throws IOException { public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din); super.readFromChannel(din);
int lth=klalbHeader.getChar(1); int lth=klalbHeader.getChar(1);
byte[]b=new byte[lth]; 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;
}
}
+6 -2
View File
@@ -2,7 +2,11 @@ package org.kne.cloud.network.klalb;
public class CONST { public class CONST {
public static final String klalb="KLALB"; 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 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); klalbHeader.putChar((char) 0);
//dataBuffer.limit(mtulimit); //dataBuffer.limit(mtulimit);
dataBuffer=ByteBuffer.allocate(mtulimit); dataBuffer=NetworkPacket.bufferAllocator.allocate(mtulimit);
} }
public int getSendcount() { public int getSendcount() {
@@ -100,7 +100,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.put(17, (byte) getSendCounter()); klalbHeader.put(17, (byte) getSendCounter());
klalbHeader.putChar(18, (char) dataBuffer.limit()); klalbHeader.putChar(18, (char) dataBuffer.limit());
super.writeToChannel(dto); super.writeToChannel(dto);
@@ -109,13 +109,13 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din) throws IOException { public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din); super.readFromChannel(din);
numberc=Long.MIN_VALUE; numberc=Long.MIN_VALUE;
int limit=klalbHeader.getChar(18); int limit=klalbHeader.getChar(18);
//dataBuffer.clear(); //dataBuffer.clear();
//dataBuffer.limit(); //dataBuffer.limit();
dataBuffer=ByteBuffer.allocate(limit); dataBuffer=NetworkPacket.bufferAllocator.allocate(limit);
while(dataBuffer.hasRemaining()){ while(dataBuffer.hasRemaining()){
if(din.read(dataBuffer)==-1) { if(din.read(dataBuffer)==-1) {
throw new EOFException(); throw new EOFException();
@@ -124,12 +124,5 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
dataBuffer.flip(); 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.DatagramSocket;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketException; import java.net.SocketException;
import java.nio.ByteBuffer;
import org.kne.cloud.network.DatagramServerSocket; import org.kne.cloud.network.DatagramServerSocket;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.SpeedLimiter;
public class DatagramKLALBPacketLink implements KLALBPacketLink { public class DatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
@Override @Override
public String toString() { public String toString() {
@@ -145,17 +147,20 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535); private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
private DataOutputStream dos=new DataOutputStream(bos); private DataOutputStream dos=new DataOutputStream(bos);
@Override /*@Override
public void writePacket(KLALBPacket kp) throws IOException { public void writeKLALBPacket(KLALBPacket kp) throws IOException {
//System.out.println(" TX:"+kp); //System.out.println(" TX:"+kp);
KLALBPacket.writeKLALBPacketToStream(dos, 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]; private byte[]bc=new byte[65535];
DataInputStream dis; DataInputStream dis;
@Override @Override
public KLALBPacket readPacket() throws IOException { public KLALBPacket readKLALBPacket() throws IOException {
KLALBPacket kp=null; KLALBPacket kp=null;
do { do {
if(dis==null) { if(dis==null) {
@@ -176,8 +181,37 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
//System.out.println(" RX:"+kp); //System.out.println(" RX:"+kp);
}while(true); }while(true);
return kp; 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 @Override
public void close() throws IOException { public void close() throws IOException {
ds.close(); ds.close();
@@ -200,10 +234,7 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
@Override @Override
public void flush() throws IOException { 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() { public boolean isStream() {
return false; 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 { public class IPv6OverKLALBPacket extends KLALBPacket {
private static final int HEADER_LENGTH=9; 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 @Override
@@ -56,12 +36,6 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
super(bb,HEADER_LENGTH); super(bb,HEADER_LENGTH);
this.ipv6Packet=new IPv6Packet(); this.ipv6Packet=new IPv6Packet();
} }
@Override
public void disposeAll() {
super.disposeAll();
ipv6Packet.disposeAll();
}
public IPv6Packet getIPv6Packet() { public IPv6Packet getIPv6Packet() {
return ipv6Packet; return ipv6Packet;
@@ -78,24 +52,16 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.putLong(1, ipv6Packet.getLength()); klalbHeader.putLong(1, ipv6Packet.getLength());
super.writeToChannel(dto); super.writeToChannel(dto);
ipv6Packet.writeToChannel(dto); ipv6Packet.writeToChannel(dto);
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
super.readFromChannel(din,length); super.readFromChannel(din,length);
ipv6Packet.readFromChannel(din, klalbHeader.getLong(1)); 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.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; 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.PacketConsumer;
import org.kne.cloud.network.srv6.SRv6Router; import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.cloud.network.te.BandwidthDistributer; import org.kne.cloud.network.te.BandwidthDistributer;
import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm; import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm;
import org.kne.concurrent.DisruptorExecutor;
import org.kne.concurrent.HighPerformanceExecutor; import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels; import org.kne.io.KNEChannels;
import org.pcap4j.packet.IpV6Packet.IpV6Header; import org.pcap4j.packet.IpV6Packet.IpV6Header;
import com.google.gson.JsonElement;
public class KLALBController { public class KLALBController {
@@ -80,6 +84,12 @@ public class KLALBController {
private static List<IPMulticastDiscovery> ipmd=new ArrayList<>(); 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); private Timer twk=new Timer("网卡检测扫描计时器", true);
{ {
@@ -210,48 +220,49 @@ public class KLALBController {
continue; continue;
} }
if(networkInterface.isUp()) { 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();) { for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next(); IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())) { if(networkInterface.equals(ipMulticastDiscovery.getNinterface())&&bidr.equals(ipMulticastDiscovery.getBind().getAddress())) {
b=false; continue loop;
break;
} }
} }
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 { try {
InetAddress bidr=InetAddress.getByName("::0"); //InetAddress bidr=InetAddress.getByName("::0");
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable);
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)->{ ipd.setCon((mpa)->{
//System.out.println("添加本地IPv6链路:"+mpa); //System.out.println("添加本地IPv6链路:"+mpa);
addRemoteLines(mpa); try {
if(!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
}); });
ipd.start(); ipd.start();
ipmd.add(ipd); ipmd.add(ipd);
}else if(bidr instanceof Inet4Address) {
bidr=InetAddress.getByName("0.0.0.0"); //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); 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)->{ ipd2.setCon((mpa)->{
//System.out.println("添加本地IPv4链路:"+mpa); //System.out.println("添加本地IPv4链路:"+mpa);
addRemoteLines(mpa); try {
if(!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
}); });
ipd2.start(); ipd2.start();
ipmd.add(ipd2); ipmd.add(ipd2);
}
System.out.println("添加网卡:"+networkInterface); System.out.println("添加网卡:"+networkInterface);
}catch(BindException e) { }catch(BindException e) {
//e.printStackTrace(); //e.printStackTrace();
@@ -259,8 +270,11 @@ public class KLALBController {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); 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); }, 2000, 2000);
} }
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() { public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
@@ -326,10 +345,10 @@ public class KLALBController {
} }
private Inet6AddressGroup self; //private Inet6AddressGroup self;
public Inet6Address getSelf() { public Inet6AddressGroup getSelf() {
return self.getAddress(); return srv6Router.getLocator();
} }
private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>(); private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
private ReadWriteLock lineslock=new ReentrantReadWriteLock(); private ReadWriteLock lineslock=new ReentrantReadWriteLock();
@@ -339,11 +358,16 @@ public class KLALBController {
} }
private PortBinder streamPortBinder=new PortBinder(this); private PortBinder streamPortBinder=new PortBinder(this);
private PortBinder rawPortBinder=new PortBinder(this);
protected PortBinder getStreamPortBinder() { protected PortBinder getStreamPortBinder() {
return streamPortBinder; return streamPortBinder;
} }
public PortBinder getRawPortBinder() {
return rawPortBinder;
}
public void reconnectImmediately() { public void reconnectImmediately() {
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) { 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<>(); List<KLALBRemoteLine>added=new ArrayList<>();
try { try {
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces(); Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
@@ -419,6 +444,9 @@ public class KLALBController {
} }
return added; return added;
}finally {
lineslock.writeLock().unlock();
}
} }
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) { public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
@@ -477,15 +505,15 @@ public class KLALBController {
} }
public void addRemoteLine(KLALBRemoteLine krs) { public void addRemoteLine(KLALBRemoteLine krs) {
lineslock.writeLock().lock();
try {
krs.setPacketReceiver(prc); krs.setPacketReceiver(prc);
krs.setKlalbController(this); krs.setKlalbController(this);
krs.setLocalVaddrSupplier(()->{return self;}); krs.setLocalVaddrSupplier(()->{return getSelf();});
krs.startIO(); krs.startIO();
String selflineTable=generateSelfLineTable(); String selflineTable=generateSelfLineTable();
if(selflineTable!=null&&!selflineTable.equals("")) if(selflineTable!=null&&!selflineTable.equals(""))
krs.sendPacket(new ADDLINESPacket(selflineTable)); krs.sendPacket(new ADDLINESPacket(selflineTable));
lineslock.writeLock().lock();
try {
lines.add(krs); lines.add(krs);
}finally { }finally {
lineslock.writeLock().unlock(); lineslock.writeLock().unlock();
@@ -502,16 +530,12 @@ public class KLALBController {
} }
return sbd.toString(); return sbd.toString();
} }
public KLALBController(Inet6Address self) {
this.self =new Inet6AddressGroup(self, PREFIX);
loadSRv6ProtocolStack();
}
private class KLALBProtocolPacketConsumer implements PacketConsumer{ private class KLALBProtocolPacketConsumer implements PacketConsumer{
@Override @Override
public void accept(IPv6Packet packx) throws IOException { public void accept(IPv6Packet packx) throws IOException {
HighPerformanceExecutor.defaultExecutor.execute(()->{ //HighPerformanceExecutor.defaultExecutor.execute(()->{
/*System.out.println("RCV:"+packx.getPayload().getData()); /*System.out.println("RCV:"+packx.getPayload().getData());
byte[]b=new byte[packx.getPayload().getData().limit()]; byte[]b=new byte[packx.getPayload().getData().limit()];
@@ -539,18 +563,18 @@ public class KLALBController {
} }
} }
} }
packx.dispose(); //packx.dispose();
}); //});
} }
} }
private void loadSRv6ProtocolStack() { private void loadSRv6ProtocolStack(Inet6AddressGroup selfx,boolean enableVirtualAdapter) {
srv6Router=new SRv6Router(self); srv6Router=new SRv6Router(selfx);
if(enableVirtualAdapter)
try { 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); tunlink.setMonitor(datatMonitor);
srv6Router.getLinkTabel().add(tunlink); srv6Router.getLinkTabel().add(tunlink);
Thread.sleep(100);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -558,8 +582,19 @@ public class KLALBController {
srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer()); srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer());
System.out.println("SRv6协议栈已加载"); System.out.println("SRv6协议栈已加载");
} }
public KLALBController() { 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(); SecureRandom sc=new SecureRandom();
byte[]v=new byte[16]; byte[]v=new byte[16];
sc.nextBytes(v); sc.nextBytes(v);
@@ -569,27 +604,31 @@ public class KLALBController {
v[3]=1; v[3]=1;
v[14]=0; v[14]=0;
v[15]=1; v[15]=1;
Inet6AddressGroup selfx=null;
try { try {
this.self=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX); selfx=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
e.printStackTrace(); 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() { protected KLALBVirtualSocketImpl createVirtualImpl() {
return new KLALBVirtualSocketImpl(this); return new KLALBVirtualSocketImpl(this);
} }
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet)
throws IOException {
sendPacketToLinkAddress(addr, packet, 1);
}
private SRv6Router srv6Router; private SRv6Router srv6Router;
@@ -603,7 +642,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
@Override @Override
public void run() { 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();) { for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next(); KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
if(klalbRemoteLine.isClosed()) { if(klalbRemoteLine.isClosed()) {
@@ -615,20 +654,20 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
} }
}else { }else {
if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) { 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); lines2.get(klalbRemoteLine.getRemoteVaddr()).getEntries().add(klalbRemoteLine);
}else { }else {
ArrayList<KLALBRemoteLine>al1=new ArrayList<>(); ArrayList<KLALBRemoteLine>al1=new ArrayList<>();
al1.add(klalbRemoteLine); al1.add(klalbRemoteLine);
lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1)); lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1));
} }*/
if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) { if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) {
srv6Router.getLinkTabel().add(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(); Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>) iterator.next();
List<KLALBRemoteLine> lineList=klalbRemoteLine.getValue().getEntries(); List<KLALBRemoteLine> lineList=klalbRemoteLine.getValue().getEntries();
lineList.forEach((r)->{ lineList.forEach((r)->{
@@ -641,7 +680,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
} }
} }
KLALBController.this.lines2=lines2; KLALBController.this.lines2=lines2;*/
if(srv6Router!=null) { if(srv6Router!=null) {
srv6Router.getLinkTabel().removeIf((v)->{ srv6Router.getLinkTabel().removeIf((v)->{
return (v instanceof KLALBRemoteLine)&&(!v.isUp()); return (v instanceof KLALBRemoteLine)&&(!v.isUp());
@@ -649,7 +688,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
srv6Router.updateRouteTabel(); srv6Router.updateRouteTabel();
} }
} }
}, 1, 1); }, 2, 2);
} }
/*private void updateLines2(Inet6Address addr) throws SocketTimeoutException { /*private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
List<KLALBRemoteLine> l=new ArrayList(); List<KLALBRemoteLine> l=new ArrayList();
@@ -675,122 +714,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
lines2.put(addr, l); lines2.put(addr, l);
} }
}*/ }*/
private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>(); //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");
}*/
}
@@ -804,11 +728,8 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
HighPerformanceExecutor.defaultExecutor.execute(()->{ HighPerformanceExecutor.defaultExecutor.execute(()->{
IPv6Packet ipv=new IPv6Packet(); IPv6Packet ipv=new IPv6Packet();
packet.getDisposeLock().lock();
try {
if(packet.isDisposed()) {
return;
}
if(showpacket) if(showpacket)
System.out.println("KLALB_TX:"+packet); System.out.println("KLALB_TX:"+packet);
@@ -816,10 +737,15 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
ipv.setTrafficClass(0); ipv.setTrafficClass(0);
ipv.setFlowLabel(flowlabel); ipv.setFlowLabel(flowlabel);
ipv.setHopLimit(255); ipv.setHopLimit(255);
ipv.setSourceAddress(self.getAddress()); ipv.setSourceAddress(getSelf().getAddress());
ipv.setDestinationAddress(addr); ipv.setDestinationAddress(addr);
ipv.setPriority(packet.getPriority()); ipv.setPriority(packet.getPriority());
if(packet instanceof DATATPacket) {
ipv.setPromise(true);
}
ipv.enableECN(); ipv.enableECN();
/* if(b)
ipv.markCE();*/
ipv.setPayload(packet); ipv.setPayload(packet);
//System.out.println(ipv.getPayload().getProtocolNumber()); //System.out.println(ipv.getPayload().getProtocolNumber());
/*System.out.println("SND:"+ipv.getPayload().getData()); /*System.out.println("SND:"+ipv.getPayload().getData());
@@ -828,13 +754,12 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
System.out.println(Arrays.toString(b));*/ System.out.println(Arrays.toString(b));*/
//packet.getSendRecord().add(null); //packet.getSendRecord().add(null);
packet.incSendCounter(); packet.incSendCounter();
}finally {
packet.getDisposeLock().unlock();
}
packet.putTimePassport("packedInIPv6"); packet.putTimePassport("packedInIPv6");
packet.printPassport(); packet.printPassport();
ipv.putTimePassport("packed"); ipv.putTimePassport("packed");
srv6Router.putProtocolNumberPacketAndInsertSRH(ipv); srv6Router.insertSRHandRoutePacket(ipv);
//srv6Router.putProtocolNumberPacketAndInsertSRHAsync(ipv);
}); });
} }
@@ -869,7 +794,11 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
try { try {
BandwidthDistributer<PortPair> bdr= bandwidthDistrmap.get(targetaAddress); BandwidthDistributer<PortPair> bdr= bandwidthDistrmap.get(targetaAddress);
if(bdr==null) { 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); bdr.setDistrUpdateConsumer(portp, updateConsumer);
@@ -920,7 +849,6 @@ private List<MultipurposeSocketAddress> listens=new CopyOnWriteArrayList<>();
} }
/*@Override /*@Override
public void listen(MultipurposeSocketAddress msa) { public void listen(MultipurposeSocketAddress msa) {
// TODO 自动生成的方法存根 // TODO 自动生成的方法存根
@@ -8,10 +8,18 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StreamCorruptedException; import java.io.StreamCorruptedException;
import java.net.Inet6Address; 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 { public class KLALBInputStream extends DataInputStream {
private ReadableByteChannel channel;
public KLALBInputStream(InputStream in) throws IOException { public KLALBInputStream(InputStream in) throws IOException {
super(in); super(in);
channel=Channels.newChannel(in);
byte[]b=new byte[5]; byte[]b=new byte[5];
readFully(b); readFully(b);
String s=new String(b,"ascii"); String s=new String(b,"ascii");
@@ -23,8 +31,16 @@ public class KLALBInputStream extends DataInputStream {
if(bv!=CONST.bversion) if(bv!=CONST.bversion)
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V"+CONST.klalbver); 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); 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;
}
} }
+33 -1
View File
@@ -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.KLALBStateGUI2;
import org.kne.cloud.network.klalb.ui.UIEnv; import org.kne.cloud.network.klalb.ui.UIEnv;
import org.kne.cloud.network.perf.Kperf; 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; import org.kne.debug.Debuger;
public class KLALBMain { public class KLALBMain {
@@ -37,7 +39,7 @@ public class KLALBMain {
KLALBProxySystem kpcje=new KLALBProxySystem(); KLALBProxySystem kpcje=new KLALBProxySystem();
kpcje.loadConfigJson(configJson); kpcje.loadConfigJson(configJson);
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getHostAddress()); System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getAddress().getHostAddress());
try { try {
openGUI(kpcje); openGUI(kpcje);
}catch(RuntimeException e) { }catch(RuntimeException e) {
@@ -152,10 +154,40 @@ public class KLALBMain {
System.out.println("请输入测速服务端地址:端口!"); 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; break;
//case "$$SYSTEM:": //case "$$SYSTEM:":
//System.out.println(); //System.out.println();
//break; //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: default:
System.out.println("未知命令,请输入help以查询命令说明"); System.out.println("未知命令,请输入help以查询命令说明");
} }
@@ -4,19 +4,29 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
public class KLALBOutputStream extends DataOutputStream { public class KLALBOutputStream extends DataOutputStream {
private WritableByteChannel channel;
public KLALBOutputStream(OutputStream out) throws IOException { public KLALBOutputStream(OutputStream out) throws IOException {
super(out); super(out);
this.channel=Channels.newChannel(out);
byte[]b=new byte[] {'K','L','A','L','B'}; byte[]b=new byte[] {'K','L','A','L','B'};
write(b); write(b);
writeInt(CONST.bversion); writeInt(CONST.bversion);
writeInt(CONST.sversion); writeInt(CONST.sversion);
flush(); flush();
} }
public void writePacket(KLALBPacket klb) throws IOException { public void writeKLALBPacket(KLALBPacket klb) throws IOException {
writeInt((int) klb.getLength());
KLALBPacket.writeKLALBPacketToStream(this, klb); 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.DataOutputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.StreamCorruptedException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; 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.NetworkPacket;
import org.kne.cloud.network.ipv6.IPv6Packet; 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 abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public static final int KLALB_PROTOCOL_NUMBER=254; 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 VADDR=8;
public static final int ADDLINES=9; public static final int ADDLINES=9;
public static final int NACKT=10; 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 VADDRACK=12;
public static final int VADDRREQ=13; public static final int VADDRREQ=13;
public static final int IPV6OVERKLALB=14; public static final int IPV6OVERKLALB=14;
public static final int ADDR=15; public static final int ADDR=15;
public static final int ADDRREQ=16; public static final int ADDRREQ=16;
public static final int TEST1=17;
//private static final int HEADER_CAPACITY = 32; //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); //public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
protected volatile ByteBuffer klalbHeader; protected ByteBuffer klalbHeader;
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) { protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
super(KLALB_PROTOCOL_NUMBER,false); super(KLALB_PROTOCOL_NUMBER,false);
@@ -55,7 +59,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public KLALBPacket(int type,int headerLength) { public KLALBPacket(int type,int headerLength) {
super(KLALB_PROTOCOL_NUMBER,false); super(KLALB_PROTOCOL_NUMBER,false);
klalbHeader=ByteBuffer.allocate(headerLength); klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
klalbHeader.put((byte) type); klalbHeader.put((byte) type);
this.headerLength=headerLength; this.headerLength=headerLength;
} }
@@ -83,7 +87,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return joinqueuetime; return joinqueuetime;
} }
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
sndtime=System.nanoTime(); sndtime=System.nanoTime();
dto.write(klalbHeader.slice(0, headerLength)); dto.write(klalbHeader.slice(0, headerLength));
} }
@@ -93,7 +97,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return false; return false;
} }
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
klalbHeader.limit(headerLength); klalbHeader.limit(headerLength);
while(klalbHeader.hasRemaining()){ while(klalbHeader.hasRemaining()){
if(din.read(klalbHeader)==-1) { if(din.read(klalbHeader)==-1) {
@@ -135,13 +139,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return klalbHeader; 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 { public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
return readKLALBPacketFromChannel(Channels.newChannel(in)); return readKLALBPacketFromChannel(Channels.newChannel(in));
@@ -149,14 +146,14 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException { public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
while(true) { while(true) {
ByteBuffer bb=databufferpool_40.borrow(); ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
bb.limit(1); bb.limit(1);
while(bb.hasRemaining()){ while(bb.hasRemaining()){
if(in.read(bb)==-1) { if(in.read(bb)==-1) {
return null; return null;
} }
} }
int type=bb.get(0); int type=bb.get(0)&0xff;
bb.limit(bb.capacity()); bb.limit(bb.capacity());
KLALBPacket klp; KLALBPacket klp;
@@ -196,8 +193,8 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
klp=new NACKTPacket(bb); klp=new NACKTPacket(bb);
klp.readFromChannel(in); klp.readFromChannel(in);
return klp; return klp;
case TEST: case TESTN:
klp=new TESTPacket(bb); klp=new TESTNPacket(bb);
klp.readFromChannel(in); klp.readFromChannel(in);
return klp; return klp;
case VADDRACK: case VADDRACK:
@@ -220,9 +217,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
klp=new ADDRREQPacket(bb); klp=new ADDRREQPacket(bb);
klp.readFromChannel(in); klp.readFromChannel(in);
return klp; return klp;
case TEST1:
klp=new TEST1Packet(bb);
klp.readFromChannel(in);
return klp;
} }
//throw new StreamCorruptedException("unknown package type:"+type); throw new StreamCorruptedException("unknown package type:"+type);
System.err.println("ignore unknown KLALBPacket type:"+type); //System.err.println("ignore unknown KLALBPacket type:"+type);
} }
} }
@@ -237,10 +238,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return null; return null;
} }
public void doDisposeAfterSend() {
if(isDisposeAfterSend())
dispose();
}
private boolean ce=false; private boolean ce=false;
public void setCE(boolean ce) { public void setCE(boolean ce) {
this.ce=ce; this.ce=ce;
@@ -2,13 +2,26 @@ package org.kne.cloud.network.klalb;
import java.io.IOException; import java.io.IOException;
import java.net.SocketException; import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
public interface KLALBPacketLink { 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 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 void close() throws IOException;
public boolean isClosed(); public boolean isClosed();
public void setSoTimeout(int val) throws SocketException; public void setSoTimeout(int val) throws SocketException;
@@ -11,11 +11,13 @@ import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -112,15 +114,43 @@ public class KLALBProxySystem {
case "KLALBController": case "KLALBController":
JsonElement vase= entry.get("VirtualAddress"); JsonElement vase= entry.get("VirtualAddress");
//System.out.println(vase); //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) { if(vase!=null) {
try { try {
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString())); klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()),daddr);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
e.printStackTrace(); e.printStackTrace();
} }
}else { }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"); JsonElement vsne=entry.get("VirtualSocketName");
//if(vsne!=null) { //if(vsne!=null) {
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType()); MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
@@ -280,7 +310,7 @@ public class KLALBProxySystem {
if(string.startsWith("SocketBridge")) { if(string.startsWith("SocketBridge")) {
return new DefaultSocketBridgeFactory(); return new DefaultSocketBridgeFactory();
}else if(string.startsWith("MinecraftSocketBridge")) { }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); throw new IllegalArgumentException("unknown SocketBridge type:"+string);
} }
@@ -5,42 +5,69 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.StreamCorruptedException;
import java.lang.foreign.MemorySegment;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.UnresolvedAddressException; import java.nio.channels.UnresolvedAddressException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.PriorityBlockingQueue; 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.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.kne.cloud.clock.AdjustedNanoClock; import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.clock.ReliabilityBackoffTimeClock; import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
import org.kne.cloud.network.ByteBufferAllocator;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool; import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6NetworkLink; import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet; 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.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor; 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.MonitorData;
import org.kne.cloud.network.monitor.NanoTimeSeries;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl; import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; 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.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 debug = false;
private static final boolean showpacket = 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 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 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() { protected void startIO() {
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> { ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1); //Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
@@ -251,87 +287,153 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
addressGroup=new Inet6AddressGroup(i6a, 112); addressGroup=new Inet6AddressGroup(i6a, 112);
} }
} else { } else {
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress); kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress,false);
} }
//startRecord(); //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); 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("远程发送线程", () -> { Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
tlock = Thread.currentThread(); tlock = Thread.currentThread();
//tlock.setPriority(Thread.NORM_PRIORITY+1); //tlock.setPriority(Thread.NORM_PRIORITY+1);
try { try {
writePacketToKPL(new ADDRREQPacket()); writeKLALBPacketToKPL(new ADDRREQPacket());
writePacketToKPL(new ADDRREQPacket()); writeKLALBPacketToKPL(new ADDRREQPacket());
if(addressGroup!=null) { if(addressGroup!=null) {
writePacketToKPL(new ADDRPacket(addressGroup)); writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
writePacketToKPL(new ADDRPacket(addressGroup)); writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
} }
writePacketToKPL(new VADDRREQPacket()); writeKLALBPacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRREQPacket()); writeKLALBPacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get())); writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get())); writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
flushKPL(); flushKPL();
KLALBPacket kpp = null; ByteBuffer[] kpp = null;
int kppslen=0;
while ((!kplink.isClosed()) && (!closed)) { while ((!kplink.isClosed()) && (!closed)) {
// TimeDebugger tdb=new TimeDebugger(); // TimeDebugger tdb=new TimeDebugger();
// tdb.putTime("start"); // tdb.putTime("start");
if(checkBandwidthReportTime()) { if(checkBandwidthReportTime()) {
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2())); sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg(), monitor.getInSpeedAvg()));
} }
if (checkPingTimeSleep()) { if (checkPingTimeSleep()) {
writePacketToKPL(new PINGPacket(System.nanoTime())); writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
if (remoteVaddr == null) if (remoteVaddr == null)
writePacketToKPL(new VADDRREQPacket()); writeKLALBPacketToKPL(new VADDRREQPacket());
if(peerAddress==null) if(peerAddress==null)
writePacketToKPL(new ADDRREQPacket()); writeKLALBPacketToKPL(new ADDRREQPacket());
}else { }else {
KLALBPacket kpip = IsendDequeList.poll(); KLALBPacket kpip = IsendDequeList.poll();
if (kpip != null) { if (kpip != null) {
writePacketToKPL(kpip); writeKLALBPacketToKPL(kpip);
}else { }else {
// tdb.putTime("Isend"); // tdb.putTime("Isend");
if (kpp == null) { if (kpp == null) {
do { ByteBuffer tkpp = sendDequeList.poll();
kpp = sendDequeList.poll(); if(tkpp==null) {
} while (kpp != null && kpp.isDisposed());
if(kpp==null) {
monitor.setQueueingDelay(0); 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()); // System.out.println(sendDequeList.size());
if (kpp != null) { if (kpp != null) {
// TimeDebugger tdb=new TimeDebugger(); // TimeDebugger tdb=new TimeDebugger();
//tdb.putTime("start"); //tdb.putTime("start");
KLALBPacket kppt=kpp;
kppt.lockAll();
try {
if (kpp.isSomeDisposed()) {
kpp = null;
} else {
// if (congress.checkTransmit(length)) { // if (congress.checkTransmit(length)) {
writePacketToKPL(kpp); kplink.writePackets(kpp,0,kppslen);
if (checkPingTime()) { 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) { /*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) {
resetSleepTimer(); resetSleepTimer();
}*/ }*/
kpp.doDisposeAfterSend();
kpp = null; kpp = null;
}
//} //}
} finally {
kppt.unlockAll();
}
//tdb.putTime("sendToLink"); //tdb.putTime("sendToLink");
//tdb.print(); //tdb.print();
}else { }else {
LockSupport.parkNanos(1000000); LockSupport.parkNanos(10000000L);
} }
} }
} }
@@ -358,6 +460,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
// System.out.println(sendDequeList.isEmpty()); // System.out.println(sendDequeList.isEmpty());
Thread.yield(); Thread.yield();
} }
}catch(StreamCorruptedException sce) {
sce.printStackTrace();
} catch (IOException | UnresolvedAddressException e) { } catch (IOException | UnresolvedAddressException e) {
if (debug) if (debug)
e.printStackTrace(); e.printStackTrace();
@@ -370,28 +474,26 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
} }
}); });
t.start(); t.start();
boolean fst = true; AtomicBoolean fst = new AtomicBoolean(true);
long stime = 5000000000L; long stime = 5000000000L;
while ((!kplink.isClosed()) && (!closed)) { while ((!kplink.isClosed()) && (!closed)) {
long readStart = System.nanoTime(); ByteBuffer kppb = kplink.readPacket();
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);
kplink.setSoTimeout(3000); kplink.setSoTimeout(3000);
kplink.setSoTimeout((int) (stime / 1000000)); if (kppb == null) {
if (kpp == null) {
break; 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()) { switch (kpp.getType()) {
case KLALBPacket.PING: case KLALBPacket.PING:
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime())); 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 DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
long DsndDelayFactor; long DsndDelayFactor;
long DrcvDelayFactor; long DrcvDelayFactor;
adjnc.getLock().lock(); AdjustedNanoClock adjc=adjnc;
adjc.getLock().lock();
try { try {
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2); adjc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
if (DsndDelayFactor < 0) { if (DsndDelayFactor < 0) {
if (DrcvDelayFactor < 0) { if (DrcvDelayFactor < 0) {
} else { } else {
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor); adjc.setDelta(adjc.getDelta() + DsndDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
} }
} else { } else {
if (DrcvDelayFactor < 0) { if (DrcvDelayFactor < 0) {
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor); adjc.setDelta(adjc.getDelta() - DrcvDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta(); DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta(); DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
} }
} }
} finally { } finally {
adjnc.getLock().unlock(); adjc.getLock().unlock();
} }
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) { if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
@@ -436,7 +539,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
//pingInterval = monitor.getLatencyAvg()+2000000L; //pingInterval = monitor.getLatencyAvg()+2000000L;
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay(); //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); LockSupport.unpark(tlock);
@@ -446,9 +549,12 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if (bwi.getDownSpeed() >= congressSpeed) { if (bwi.getDownSpeed() >= congressSpeed) {
congressSpeed = bwi.getDownSpeed(); congressSpeed = bwi.getDownSpeed();
} else { } 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); // System.out.println(congressSpeed);
break; break;
case KLALBPacket.ADDRREQ: case KLALBPacket.ADDRREQ:
@@ -460,7 +566,13 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if(addressGroup==null) { if(addressGroup==null) {
byte[]ab=peerAddress.getAddress().getAddress(); byte[]ab=peerAddress.getAddress().getAddress();
ab[15]=2; 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; addressGroup=ardg2;
} }
break; break;
@@ -475,39 +587,124 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if (klalbController != null) { if (klalbController != null) {
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress()); adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
} }
if (fst) { if (fst.compareAndSet(true, false)) {
// coll.resetCoolingTime(); // coll.resetCoolingTime();
monitor.setState(MonitorData.ONLINE); monitor.setState(MonitorData.ONLINE);
fst = false;
} }
break; break;
case KLALBPacket.VADDRACK: case KLALBPacket.VADDRACK:
break; break;
case KLALBPacket.TEST: case KLALBPacket.TESTN:
break; break;
case KLALBPacket.IPV6OVERKLALB: case KLALBPacket.IPV6OVERKLALB:
if(ipv6con!=null) {
IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp; IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp;
IPv6Packet iv6= ivk.getIPv6Packet(); IPv6Packet iv6= ivk.getIPv6Packet();
ivk.putTimePassport("unpacked"); ivk.putTimePassport("unpacked");
ivk.printPassport(); ivk.printPassport();
iv6.putTimePassport("unpackFromLink"); 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); ipv6con.accept(iv6);
}
}
} }
break; break;
default: default:
while (rec == null) { if(rec!=null)
Thread.sleep(1);
}
rec.accept( kpp); rec.accept( kpp);
break; break;
} }
});
Thread.yield(); Thread.yield();
} }
}catch(StreamCorruptedException sce) {
sce.printStackTrace();
} catch (IOException | UnresolvedAddressException e) { } catch (IOException | UnresolvedAddressException e) {
if (debug) if (debug)
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { }catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
monitor.setState(MonitorData.OFFLINE); monitor.setState(MonitorData.OFFLINE);
@@ -518,17 +715,14 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
/*KLALBPacket pack; Collection<SendItem>vals= sendMap.values();
while((pack=sendDequeList.poll())!=null) { SendItem[]packs= vals.toArray(new SendItem[0]);
try { for (SendItem iPv6Packet : packs) {
if(remoteVaddr!=null) { rerouteConsumer.accept(iPv6Packet.getPacket());
klalbController.sendPacketToLinkAddress(remoteVaddr, pack); //System.out.println("重路由:"+iPv6Packet);
if(debug)
System.out.println("RETRY:"+pack);
}
} catch (IOException e) {
} }
}*/ sendMap.clear();
sendmapWindowUsed.set(0);
} }
if (closed) { if (closed) {
@@ -544,63 +738,98 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}).start(); }).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 { private void flushKPL() throws IOException {
kplink.flush(); kplink.flush();
} }
private KLALBPacket readPacketFromKPL() throws IOException { private KLALBPacket readKLALBPacketFromKPL() throws IOException {
KLALBPacket packet = kplink.readPacket(); KLALBPacket packet = kplink.readKLALBPacket();
if (showpacket) { debugShowPacket("RX",packet);
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.out.println("RX:" + packet);
}
if (packet != null) { if (packet != null) {
packet.putTimePassport("received"); 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; return packet;
} }
private void writePacketToKPL(KLALBPacket packet) throws IOException { private void writeKLALBPacketToKPL(KLALBPacket packet) throws IOException {
long length=packet.getLength(); kplink.writeKLALBPacket(packet);
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
packet.putTimePassport("sended"); packet.putTimePassport("sended");
packet.printPassport(); packet.printPassport();
if (showpacket) { debugShowPacket("TX",packet);
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.err.println("TX:" + packet);
}
} }
private void writePacketToKPL(KLALBPacket packet,long length) throws IOException { private void debugShowPacket(String label, KLALBPacket packet) {
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
if (showpacket) { if (showpacket) {
if (!(packet instanceof PINGPacket)) if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket)) if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket)) 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 time = System.nanoTime();
private volatile long pingInterval = 10000000L; private volatile long pingInterval = 10000000L;
private volatile long pingIntervalSleep = 200000000L; private volatile long pingIntervalSleep = 500000000L;
private boolean checkPingTime() { private boolean checkPingTime() {
long cu = System.nanoTime(); long cu = System.nanoTime();
@@ -649,7 +878,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private volatile long bwtime = System.nanoTime(); private volatile long bwtime = System.nanoTime();
private volatile long bwpingInterval = 10000000L; private volatile long bwpingInterval = 10000000L;
private volatile long bwpingIntervalSleep = 100000000L; private volatile long bwpingIntervalSleep = 200000000L;
private boolean checkBandwidthReportTime(){ private boolean checkBandwidthReportTime(){
long cu = System.nanoTime(); long cu = System.nanoTime();
if (cu - bwtime > bwpingIntervalSleep) { if (cu - bwtime > bwpingIntervalSleep) {
@@ -667,16 +896,25 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>(); 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; return sendDequeList;
} }
protected void sendPacket(KLALBPacket blk) { protected void sendPacket(KLALBPacket blk) {
debugShowPacket("TX",blk);
blk.markJoinqueuetime(); 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); LockSupport.unpark(tlock);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
} }
private void sendIPacket(KLALBPacket blk) { private void sendIPacket(KLALBPacket blk) {
@@ -688,21 +926,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
this.rec = rec; 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; 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 volatile boolean pressure = false;
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768); private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
@@ -774,46 +999,21 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
return predictTime; return predictTime;
} }
private List<Double>ranks=new ArrayList<Double>();
private Consumer<IPv6Packet> ipv6con; 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 @Override
public boolean isLoopBack() { public boolean isLoopBack() {
return false; return false;
} }
private BandwidthDistributer<Inet6Address> bandwidthDistributer=new BandwidthDistributer<Inet6Address>();
@Override @Override
public List<Neighbor> getNeighborsInfo() { public List<Neighbor> getNeighborsInfo() {
List<Neighbor>hs=new ArrayList<>(); List<Neighbor>hs=new ArrayList<>();
if(peerAddress!=null) { if(peerAddress!=null) {
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor)); hs.add(new Neighbor(peerAddress, remoteVaddr, monitor,bandwidthDistributer));
//System.out.println(peerAddress+" "+addressGroup); //System.out.println(peerAddress+" "+addressGroup);
} }
return hs; 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 @Override
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException { public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException {
pack.lockAll(); //只有已连接的链路才能传输数据
try { if(monitor.getState()==MonitorData.ONLINE) {
if(pack.isSomeDisposed()) {
return; //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); IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack);
kipv6.setPriority(pack.getPriority()); kipv6.setPriority(pack.getPriority());
kipv6.setDisposeAfterSend(true);
pack.putTimePassport("packdInLink"); pack.putTimePassport("packdInLink");
pack.printPassport(); pack.printPassport();
sendPacketToLink(kipv6); sendPacketToLink(kipv6);
}
}finally {
pack.unlockAll();
}
} }
private void sendPacketToLink(KLALBPacket packet) { private void sendPacketToLink(KLALBPacket packet) {
@@ -850,13 +1101,18 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
} }
@Override @Override
public boolean isCongress(IPv6Packet iPv6Packet) { public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
int size=getQueue().size(); if(monitor.getInDelay()>3000000000L||monitor.getOutDelay()>3000000000L||monitor.getInSpeedAvg()<=0||monitor.getOutSpeedAvg()<=0)
if(size>30) {
return true; return true;
}else { boolean congress=sendmapWindowUsed.get()>reallimit*scale;
return !congress.checkTransmit(iPv6Packet.getLength()); return congress;
}
}
@Override
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
boolean xcongress=!congress.checkTransmit(iPv6Packet.getLength());
return xcongress;
} }
@Override @Override
@@ -879,6 +1135,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
this.ipv6con=ipv6con; 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;
}
} }
+143 -3
View File
@@ -10,6 +10,8 @@ import java.net.UnknownHostException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
@@ -135,8 +137,28 @@ public class KLALBUtils {
Color col=new Color( r,g,0); Color col=new Color( r,g,0);
return col; 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 { throws IOException {
if (targetAddress.isStream()) { if (targetAddress.isStream()) {
if (targetAddress.supportNIO()) { if (targetAddress.supportNIO()) {
@@ -164,14 +186,23 @@ public class KLALBUtils {
} }
} }
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, 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.isStream()) {
if (targetAddress.supportNIO()) { if (targetAddress.supportNIO()) {
if (bindAddress != null) { if (bindAddress != null) {
if(buffered) {
return new StreamChannelKLALBPacketLink(targetAddress
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
}else {
return new StreamChannelKLALBPacketLink(targetAddress return new StreamChannelKLALBPacketLink(targetAddress
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout)); .connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
}
} else { } else {
if(buffered) {
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
}else {
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout)); return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
}
} }
} else { } else {
if (bindAddress != null) { 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(); return (KLALBVirtualSocketImpl) super.getVirtualImpl();
} }
private KLALBController controler; private KLALBController controller;
protected SocketChannel channel; protected SocketChannel channel;
public KLALBVirtualSocket(KLALBController controler) throws SocketException { public KLALBVirtualSocket(KLALBController controler) throws SocketException {
super(controler.createVirtualImpl()); super(controler.createVirtualImpl());
this.controler = controler; this.controller = controler;
} }
protected KLALBController getControler() { protected KLALBController getController() {
return controler; return controller;
} }
public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException { public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException {
@@ -115,8 +115,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
@Override @Override
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
// TODO 自动生成的方法存根 return ((KVSIInputStream)socket.getInputStream()).read(dsts,offset,length);
return 0;
} }
@Override @Override
@@ -126,8 +125,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
@Override @Override
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
// TODO 自动生成的方法存根 return ((KVSIOutputStream)socket.getOutputStream()).write(srcs,offset,length);
return 0;
} }
@Override @Override
@@ -151,4 +149,10 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
socket.associateSocketChannel(b); 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; this.controller = controller;
} }
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock(); 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 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 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; private volatile int portn=65535;
public void bind(BindableKLALBPacketConsumer ks) throws BindException { public void bind(BindableKLALBPacketConsumer ks) throws BindException {
bindMaplock.writeLock().lock(); bindMaplock.writeLock().lock();
@@ -205,7 +205,7 @@ public class PortBinder {
return b; return b;
}*/ }*/
public boolean distributePacketToConsumer(Inet6Address srcAddr,PortPacket packet) { 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()); InetSocketAddress remote=new InetSocketAddress(srcAddr, packet.getSport());
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote)); BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
if(bkc!=null) { 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.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.DatagramServerSocket; import org.kne.cloud.network.DatagramServerSocket;
import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket; import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.PacketRebuilder; import org.kne.cloud.network.PacketRebuilder;
import org.kne.cloud.network.PacketSpliter; import org.kne.cloud.network.PacketSpliter;
import org.kne.cloud.network.SpeedLimiter; import org.kne.cloud.network.SpeedLimiter;
import org.kne.debug.TimeDebugger; import org.kne.debug.TimeDebugger;
public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink { public class SplitedDatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
private PacketSpliter pslr=new PacketSpliter(65535); private PacketSpliter pslr;
private PacketRebuilder pbdr=new PacketRebuilder(1000000000); private PacketRebuilder pbdr;
@Override @Override
public String toString() { public String toString() {
@@ -151,13 +153,60 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException { public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
this.ds=connectDatagramSocket; 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 /*@Override
public void writePacket(KLALBPacket kp) throws IOException { public void writeKLALBPacket(KLALBPacket kp) throws IOException {
//System.out.println(" TX:"+kp); //System.out.println(" TX:"+kp);
//KLALBPacket.writeKLALBPacketToStream(dos, kp); //KLALBPacket.writeKLALBPacketToStream(dos, kp);
KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() { KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() {
@@ -184,47 +233,21 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
} }
}, kp); }, kp);
} }*/
private byte[]bc=new byte[65535]; private byte[]bc=new byte[65535];
private ByteBuffer bibf=ByteBuffer.allocate(65535); //private ByteBuffer bibf=ByteBuffer.allocate(65535);
@Override /*@Override
public KLALBPacket readPacket() throws IOException { public KLALBPacket readKLALBPacket() throws IOException {
KLALBPacket kp=null; KLALBPacket kp=null;
do { do {
if(bibf.remaining()<=0) { if(bibf.remaining()<=0) {
bibf.clear(); bibf.clear();
/*DatagramPacket dp=new DatagramPacket(bc, bc.length);
ds.receive(dp); pbdr.read(bibf );
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();
}
} );
bibf.flip(); bibf.flip();
} }
@@ -259,7 +282,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
}while(true); }while(true);
return kp; return kp;
} }
*/
@Override @Override
public void close() throws IOException { public void close() throws IOException {
ds.close(); ds.close();
@@ -280,7 +303,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
return ds.getSoTimeout(); return ds.getSoTimeout();
} }
@Override /*@Override
public void flush() throws IOException { public void flush() throws IOException {
bbf.flip(); bbf.flip();
//TimeDebugger tdb=new TimeDebugger(); //TimeDebugger tdb=new TimeDebugger();
@@ -307,16 +330,34 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
}); });
//tdb.putTime("flushEnd"); //tdb.putTime("flushEnd");
//tdb.print(); //tdb.print();
/*byte[]bt=bbf.array();
DatagramPacket dp=new DatagramPacket(bt,bbf.limit());
ds.send(dp);*/
bbf.clear(); bbf.clear();
} }*/
@Override @Override
public boolean isStream() { public boolean isStream() {
return false; 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; package org.kne.cloud.network.klalb;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
@@ -19,14 +20,19 @@ import java.nio.channels.Channels;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; 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.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.TimeoutTimer; 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 long timeoutTimer;
private volatile boolean timerenabled=false; private volatile boolean timerenabled=false;
private Thread timeouter=new Thread() { private Runnable timeouter=new Runnable() {
public void run() { public void run() {
timeoutTimer=System.nanoTime(); timeoutTimer=System.nanoTime();
while(connectSocket.isOpen()) { while(connectSocket.isOpen()) {
@@ -38,7 +44,7 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
} }
} }
try { try {
Thread.sleep(1); Thread.sleep(5);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -59,29 +65,13 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException { public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
this.connectSocket=connectSocket; this.connectSocket=connectSocket;
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true); connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
timeouter.start(); ThreadTool.makeVDaemonThread("连接超时计时线程", timeouter);
new KLALBOutputStream(Channels.newOutputStream(connectSocket)); new KLALBOutputStream(Channels.newOutputStream(connectSocket));
new KLALBInputStream(Channels.newInputStream(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 @Override
public void close() throws IOException { public void close() throws IOException {
@@ -113,5 +103,136 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
public boolean isStream() { public boolean isStream() {
return true; 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.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.nio.Buffer; import java.nio.Buffer;
import java.nio.ByteBuffer;
import org.kne.cloud.network.MultipurposeSocketAddress; import org.kne.cloud.network.MultipurposeSocketAddress;
public class StreamKLALBPacketLink implements KLALBPacketLink { public class StreamKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
@Override @Override
public String toString() { public String toString() {
@@ -30,13 +31,13 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
} }
@Override @Override
public void writePacket(KLALBPacket kp) throws IOException { public void writeKLALBPacket(KLALBPacket kp) throws IOException {
out.writePacket(kp); out.writeKLALBPacket(kp);
} }
@Override @Override
public KLALBPacket readPacket() throws IOException { public KLALBPacket readKLALBPacket() throws IOException {
return in.readPacket(); return in.readKLALBPacket();
} }
@Override @Override
@@ -68,5 +69,15 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
public boolean isStream() { public boolean isStream() {
return true; 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.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout; import java.awt.GridLayout;
import java.awt.MenuItem; import java.awt.MenuItem;
import java.awt.Point;
import java.awt.PopupMenu; import java.awt.PopupMenu;
import java.awt.Rectangle;
import java.awt.SystemTray; import java.awt.SystemTray;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.TrayIcon; import java.awt.TrayIcon;
@@ -18,7 +21,14 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; 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.io.IOException;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@@ -32,7 +42,9 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder; import javax.swing.border.LineBorder;
import org.jfree.chart.ChartPanel; 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.plot.dial.StandardDialScale;
import org.jfree.chart.ui.RectangleEdge; import org.jfree.chart.ui.RectangleEdge;
import org.jfree.data.general.DefaultValueDataset; 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.MultipurposeSocketAddress;
import org.kne.cloud.network.klalb.CONST; import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController; import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils; 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.cloud.network.monitor.MonitorData;
import org.kne.ui.XFrame; import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane; import org.kne.ui.YScrollPane;
@@ -63,8 +78,6 @@ public class KLALBStateGUI2 extends XFrame {
private TrayIcon ti; private TrayIcon ti;
private long rate=200;
private Timer t,t2,t3; private Timer t,t2,t3;
private JCheckBoxMenuItem showoffline; private JCheckBoxMenuItem showoffline;
@@ -103,13 +116,16 @@ public class KLALBStateGUI2 extends XFrame {
private DefaultValueDataset downEfficiency;*/ private DefaultValueDataset downEfficiency;*/
private YScrollPane ysp; private YScrollPane ysp,yspc;
private JTextField devicesOnline; private JTextField devicesOnline;
private JTextField textField; private JTextField textField;
private JTextField addressField; private JTextField addressField;
private JTextField addressField2;
private JTextField asnField;
private NetworkGraphPanel graph; private NetworkGraphPanel graph;
private JTextField textFieldLocate;
/** /**
@@ -771,11 +787,135 @@ public class KLALBStateGUI2 extends XFrame {
JPanel panel_4 = new JPanel(); JPanel panel_4 = new JPanel();
panel_3.add(panel_4, BorderLayout.NORTH); 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 = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol());
graph.setOpaque(false); 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); 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() { textField.addKeyListener(new KeyListener() {
@Override @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) { private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
if(tsk!=null) { if(tsk!=null) {
tsk.cancel(); tsk.cancel();
@@ -920,13 +1096,22 @@ public class KLALBStateGUI2 extends XFrame {
if(!contt.equals(devicesOnline.getText())) { if(!contt.equals(devicesOnline.getText())) {
devicesOnline.setText(contt); devicesOnline.setText(contt);
} }
String address=kc.getSelf().getHostAddress(); String address=kc.getSelf().getAddress().getHostAddress();
if(!address.equals(addressField.getText())) { if(!address.equals(addressField.getText())) {
addressField.setText(address); 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) { if(tsk3!=null) {
tsk3.cancel(); tsk3.cancel();
@@ -970,7 +1155,7 @@ public class KLALBStateGUI2 extends XFrame {
} }
} }
}; };
t3.scheduleAtFixedRate(tsk4, 200, 10); t3.scheduleAtFixedRate(tsk4, 200, 20);
if(tsk5!=null) { if(tsk5!=null) {
tsk5.cancel(); tsk5.cancel();
} }
@@ -978,11 +1163,15 @@ public class KLALBStateGUI2 extends XFrame {
@Override @Override
public void run() { public void run() {
if(graph.isVisible()) graph.loadNodes();
graph.runPhy();
if(graph.isVisible()) {
graph.repaint(); graph.repaint();
graph.revalidate();
}
} }
}; };
t.scheduleAtFixedRate(tsk5, 200, 2000); t.scheduleAtFixedRate(tsk5, 200, 100);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} }
@@ -2,6 +2,7 @@ package org.kne.cloud.network.klalb.ui;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
@@ -14,6 +15,7 @@ import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.image.ImageObserver; import java.awt.image.ImageObserver;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress;
import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -26,240 +28,80 @@ import java.util.Set;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol; import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection; import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
public class NetworkGraphPanel extends JPanel { public class NetworkGraphPanel extends GraphPanel {
private KLALBRoutingProtocol routingProtocol; 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) { public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) {
super(); super();
this.routingProtocol = routingProtocol; this.routingProtocol = routingProtocol;
//setSize(10000, 10000);
//setPreferredSize(getSize());
} }
@Override
public void paint(Graphics g) { private class InetGraphNode extends GraphNode{
super.paint(g);
loadNodes(); private InetAddress address;
Graphics2D g2d=(Graphics2D)g; public InetGraphNode() {
super();
for (Iterator<GraphEdgeGroup> iterator = edgeGroups.iterator(); iterator.hasNext();) { }
GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next();
graphNode.paint(g2d); 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(); Map<Inet6Address, Long> addr= routingProtocol.getAddresses();
Set<Inet6Address> ks=addr.keySet(); Set<Inet6Address> ks=addr.keySet();
for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) { for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next(); Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!nodes.containsKey(inet6Address)) if(!getNodes().containsKey(inet6Address)) {
nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50))); 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=nodes.keySet(); }
}
Set<Inet6Address> kns=getNodes().keySet();
for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) { for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next(); Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!addr.containsKey(inet6Address)) { if(!addr.containsKey(inet6Address)) {
@@ -267,32 +109,53 @@ public class NetworkGraphPanel extends JPanel {
} }
} }
//System.out.println("------------------------------------"); //System.out.println("------------------------------------");
edgeGroups.clear(); synchronized (getEdgeGroups()) {
Map<Inet6Address, Set<LinkDirection>> addr1= routingProtocol.getPaths();
Set<Entry<Inet6Address, Set<LinkDirection>>> salink=addr1.entrySet(); getEdgeGroups().clear();
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) { Map<Inet6Address, List<LinkDirection>> addr1= routingProtocol.getPaths();
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next(); Set<Entry<Inet6Address, List<LinkDirection>>> salink=addr1.entrySet();
Set<LinkDirection>lps=entry.getValue(); 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();) { for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
LinkDirection linkPath = (LinkDirection) iterator2.next(); LinkDirection linkPath = (LinkDirection) iterator2.next();
//System.out.println(linkPath); //System.out.println(linkPath);
GraphNode nfrom=nodes.get(linkPath.getFromLocator()); InetGraphNode nfrom=(InetGraphNode) getNodes().get(linkPath.getFromLocator());
GraphNode nto=nodes.get(linkPath.getToLocator()); InetGraphNode nto=(InetGraphNode) getNodes().get(linkPath.getToLocator());
if(nfrom!=null&&nto!=null) {
GraphEdgeGroup group=getGroup(nfrom, nto); 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) { private GraphEdgeGroup getGroup(InetGraphNode a,InetGraphNode b) {
for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) { for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next(); GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
if(graphEdgeGroup.match(a,b)) { if(graphEdgeGroup.match(a,b)) {
return graphEdgeGroup; return graphEdgeGroup;
} }
} }
GraphEdgeGroup ng=new GraphEdgeGroup(a, b); GraphEdgeGroup ng=new InetGraphEdgeGroup(a, b);
edgeGroups.add(ng); 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; return ng;
} }
} }
@@ -10,6 +10,7 @@ import javax.swing.SwingConstants;
import javax.swing.border.LineBorder; import javax.swing.border.LineBorder;
import org.kne.cloud.network.MultipurposeSocketAddress; 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.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine; import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.klalb.KLALBUtils;
@@ -93,7 +94,7 @@ public class TPanel2 extends JPanel {
targup.setHorizontalTextPosition(SwingConstants.LEFT); targup.setHorizontalTextPosition(SwingConstants.LEFT);
setBorder(new LineBorder(Color.LIGHT_GRAY)); setBorder(new LineBorder(Color.LIGHT_GRAY));
setSize(720, 45); setSize(CONST.itemwidth, CONST.linepanelheight);
setPreferredSize(getSize()); setPreferredSize(getSize());
JPanel panel = new JPanel(); JPanel panel = new JPanel();
@@ -90,7 +90,7 @@ public class SimpleKLALBMinecraftServer {
try { try {
s=mpsa2.connectSocket(); s=mpsa2.connectSocket();
MinecraftSocketBridge dsb=new MinecraftSocketBridge(pds, s); 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(); dsb.run();
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
// TODO 自动生成的 catch // TODO 自动生成的 catch
@@ -129,7 +129,7 @@ public class SimpleKLALBMinecraftServer {
//soc.setTcpNoDelay(true); //soc.setTcpNoDelay(true);
//((KLALBVirtualSocket) soc).setCompress(1); //((KLALBVirtualSocket) soc).setCompress(1);
MinecraftSocketBridge dsb=new MinecraftSocketBridge(soc, s); 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.getSab().setDelay(1);
dsb.run(); dsb.run();
/*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc); /*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc);
@@ -2,7 +2,7 @@ package org.kne.cloud.network.monitor;
import java.util.function.Consumer; import java.util.function.Consumer;
public interface MonitorData { public interface MonitorData extends Cloneable {
public static final int OFFLINE=0; public static final int OFFLINE=0;
public static final int CONNECTING=1; public static final int CONNECTING=1;
public static final int ONLINE=2; public static final int ONLINE=2;
@@ -30,4 +30,6 @@ public double getReliability();
throw new IllegalArgumentException("Unknown state:"+state); throw new IllegalArgumentException("Unknown state:"+state);
} }
} }
public Object clone() throws CloneNotSupportedException;
} }
@@ -86,4 +86,9 @@ private TimerTask ptt=new TimerTask() {
public double getReliability() { public double getReliability() {
return reliability; 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() { protected void createTask1() {
getTimer().scheduleAtFixedRate(tmt1, 0, 1000); getTimer().scheduleAtFixedRate(tmt1, 0, 500);
} }
protected void createTask2() { protected void createTask2() {
getTimer().scheduleAtFixedRate(tmt2, 0, 5000); getTimer().scheduleAtFixedRate(tmt2, 0, 5000);
@@ -123,24 +123,24 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inTraffic!=null) { if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld; long i=inTraffic.get()-inTrafficOld;
inTrafficOld =inTraffic.get(); inTrafficOld =inTraffic.get();
inSpeed= i*1000000000/d; inSpeed= (long) (i*1000000000.0/d);
} }
if(outTraffic!=null) { if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld; long o=outTraffic.get()-outTrafficOld;
outTrafficOld =outTraffic.get(); outTrafficOld =outTraffic.get();
outSpeed= o*1000000000/d; outSpeed= (long) (o*1000000000.0/d);
} }
if(inCounter!=null) { if(inCounter!=null) {
long i=inCounter.get()-inCounterOld; long i=inCounter.get()-inCounterOld;
inCounterOld =inCounter.get(); inCounterOld =inCounter.get();
inPPS= i*1000000000/d; inPPS= (long) (i*1000000000.0/d);
} }
if(outCounter!=null) { if(outCounter!=null) {
long i=outCounter.get()-outCounterOld; long i=outCounter.get()-outCounterOld;
outCounterOld =outCounter.get(); outCounterOld =outCounter.get();
outPPS= i*1000000000/d; outPPS= (long) (i*1000000000.0/d);
} }
} }
if(outSpeed>=outSpeedMax) { if(outSpeed>=outSpeedMax) {
@@ -182,25 +182,25 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inTraffic!=null) { if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld1; long i=inTraffic.get()-inTrafficOld1;
inTrafficOld1 =inTraffic.get(); inTrafficOld1 =inTraffic.get();
inSpeedAvg= i*1000000000/d; inSpeedAvg= (long) (i*1000000000.0/d);
} }
if(outTraffic!=null) { if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld1; long o=outTraffic.get()-outTrafficOld1;
outTrafficOld1 =outTraffic.get(); outTrafficOld1 =outTraffic.get();
outSpeedAvg= o*1000000000/d; outSpeedAvg= (long) (o*1000000000.0/d);
} }
if(inCounter!=null) { if(inCounter!=null) {
long i=inCounter.get()-inCounterOld1; long i=inCounter.get()-inCounterOld1;
inCounterOld1 =inCounter.get(); inCounterOld1 =inCounter.get();
inPPSAvg= i*1000000000/d; inPPSAvg= (long) (i*1000000000.0/d);
} }
if(outCounter!=null) { if(outCounter!=null) {
long o=outCounter.get()-outCounterOld1; long o=outCounter.get()-outCounterOld1;
outCounterOld1 =outCounter.get(); 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) { if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld2; long i=inTraffic.get()-inTrafficOld2;
inTrafficOld2 =inTraffic.get(); inTrafficOld2 =inTraffic.get();
inSpeedAvg2= i*1000000000/d; inSpeedAvg2= (long) (i*1000000000.0/d);
} }
if(outTraffic!=null) { if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld2; long o=outTraffic.get()-outTrafficOld2;
outTrafficOld2 =outTraffic.get(); 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) { if(inCounter!=null) {
long i=inCounter.get()-inCounterOld2; long i=inCounter.get()-inCounterOld2;
inCounterOld2 =inCounter.get(); inCounterOld2 =inCounter.get();
inPPSAvg2= i*1000000000/d; inPPSAvg2= (long) (i*1000000000.0/d);
} }
if(outCounter!=null) { if(outCounter!=null) {
long o=outCounter.get()-outCounterOld2; long o=outCounter.get()-outCounterOld2;
outCounterOld2 =outCounter.get(); outCounterOld2 =outCounter.get();
outPPSAvg2= o*1000000000/d; outPPSAvg2= (long) (o*1000000000.0/d);
} }
} }
+29 -27
View File
@@ -24,7 +24,6 @@ import org.kne.cloud.network.klalb.KLALBPacketLink;
import org.kne.cloud.network.klalb.KLALBUtils; import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.klalb.PINGPacket; import org.kne.cloud.network.klalb.PINGPacket;
import org.kne.cloud.network.klalb.PONGPacket; 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.VADDRACKPacket;
import org.kne.cloud.network.klalb.VADDRPacket; import org.kne.cloud.network.klalb.VADDRPacket;
import org.kne.cloud.network.klalb.VADDRREQPacket; 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 SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
private static long MIN_SPEED=64*1024L; 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 long congressSpeed = 0;
private double loadPercent = 1.01; private double loadPercent = 1.01;
private volatile int testSize=0; KLALBPacket testPacket=null;
//kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564 //kperf {KLALB_Stream}[2486:1:f189:7589:f1f7:6f5e:b2eb:1]:4564
//kperf {KLALB_Stream}[2486:1::8888]:4564
@Override @Override
public void run() { public void run() {
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> { 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.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0);
System.out.println("等待时间"+wtimes+"s"); System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);*/ Thread.sleep(wtimes*1000);
*/
startTime=System.nanoTime(); startTime=System.nanoTime();
if(targetAddress!=null) { if(targetAddress!=null) {
System.out.println("测试2/4:下载带宽测试"); System.out.println("测试2/4:下载带宽测试");
test.setLimitspeed(0); test.setLimitspeed(0);
testSize=60000; testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg())); System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
@@ -118,7 +118,7 @@ public class Kperf implements Runnable{
}else { }else {
System.out.println("测试2/4:上传带宽测试"); System.out.println("测试2/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L); test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000; testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg())); System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
@@ -135,7 +135,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) { if(targetAddress!=null) {
System.out.println("测试3/4:上传带宽测试"); System.out.println("测试3/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L); test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000; testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg())); System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
@@ -146,7 +146,7 @@ public class Kperf implements Runnable{
}else { }else {
System.out.println("测试3/4:下载带宽测试"); System.out.println("测试3/4:下载带宽测试");
test.setLimitspeed(0); test.setLimitspeed(0);
testSize=60000; testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg())); System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
@@ -162,7 +162,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) { if(targetAddress!=null) {
System.out.println("测试2/4:下载包转发率测试"); System.out.println("测试2/4:下载包转发率测试");
test.setLimitspeed(0); test.setLimitspeed(0);
testSize=0; testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS())); System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
@@ -171,7 +171,7 @@ public class Kperf implements Runnable{
}else { }else {
System.out.println("测试2/4:上传包转发率测试"); System.out.println("测试2/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L); test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0; testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS())); System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
@@ -186,7 +186,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) { if(targetAddress!=null) {
System.out.println("测试3/4:上传包转发率测试"); System.out.println("测试3/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L); test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0; testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS())); System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
@@ -196,7 +196,7 @@ public class Kperf implements Runnable{
}else { }else {
System.out.println("测试3/4:下载包转发率测试"); System.out.println("测试3/4:下载包转发率测试");
test.setLimitspeed(0); test.setLimitspeed(0);
testSize=0; testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) { for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0); System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS())); System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
@@ -206,17 +206,19 @@ public class Kperf implements Runnable{
} }
System.out.println("等待时间"+wtimes+"s"); System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000); Thread.sleep(wtimes*1000);
System.out.println("测速结束!");
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); System.out.println("测速被中断!");
} }finally {
System.out.println("测速结束!");
close(); close();
}
}); });
try { try {
monitor.setState(MonitorData.CONNECTING); monitor.setState(MonitorData.CONNECTING);
if(link==null) if(link==null)
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000); link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000);
link.setSoTimeout(20000); link.setSoTimeout(20000);
@@ -243,10 +245,9 @@ public class Kperf implements Runnable{
}else { }else {
KLALBPacket testp=testPacket;
if (test.checkTransmit(testSize+3)) { if (testp!=null&&test.checkTransmit(testp.getLength())) {
TESTPacket tp=new TESTPacket(testSize); writePacketToKPL(testp);
writePacketToKPL(tp);
@@ -351,7 +352,7 @@ public class Kperf implements Runnable{
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) ); congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
// System.out.println(congressSpeed); // System.out.println(congressSpeed);
break; break;
case KLALBPacket.TEST: case KLALBPacket.TESTN:
break; break;
} }
Thread.yield(); Thread.yield();
@@ -371,6 +372,7 @@ public class Kperf implements Runnable{
e.printStackTrace(); e.printStackTrace();
} }
} }
tc.interrupt();
} }
} }
private volatile long time = System.nanoTime(); private volatile long time = System.nanoTime();
@@ -441,7 +443,7 @@ public class Kperf implements Runnable{
private KLALBPacket readPacketFromKPL() throws IOException { private KLALBPacket readPacketFromKPL() throws IOException {
KLALBPacket packet = link.readPacket(); KLALBPacket packet = link.readKLALBPacket();
if (showpacket) { if (showpacket) {
System.out.println("RX:" + packet); System.out.println("RX:" + packet);
@@ -459,7 +461,7 @@ public class Kperf implements Runnable{
long length=packet.getLength(); long length=packet.getLength();
monitor.getOutTrafficAL().addAndGet(length); monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet(); monitor.getOutPacketCounterAL().incrementAndGet();
link.writePacket(packet); link.writeKLALBPacket(packet);
link.flush(); link.flush();
packet.putTimePassport("sended"); packet.putTimePassport("sended");
packet.printPassport(); 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";
}
}
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb; package org.kne.cloud.network.perf;
import java.io.DataInput; import java.io.DataInput;
import java.io.DataInputStream; import java.io.DataInputStream;
@@ -11,8 +11,9 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.NetworkPacket; 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; private static final int HEADER_LENGTH=3;
@@ -23,8 +24,8 @@ public class TESTPacket extends KLALBPacket {
} }
public TESTPacket(int limit) { public TESTNPacket(int limit) {
super(TEST,HEADER_LENGTH); super(TESTN,HEADER_LENGTH);
//dataBuffer.limit(limit); //dataBuffer.limit(limit);
dataBuffer=ByteBuffer.allocate(limit); dataBuffer=ByteBuffer.allocate(limit);
} }
@@ -37,7 +38,7 @@ public class TESTPacket extends KLALBPacket {
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.putChar(1, (char) dataBuffer.limit()); klalbHeader.putChar(1, (char) dataBuffer.limit());
super.writeToChannel(dto); super.writeToChannel(dto);
//System.out.println(dataBuffer); //System.out.println(dataBuffer);
@@ -45,7 +46,7 @@ public class TESTPacket extends KLALBPacket {
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din) throws IOException { public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din); super.readFromChannel(din);
int limit=klalbHeader.getChar(1); int limit=klalbHeader.getChar(1);
//dataBuffer.clear(); //dataBuffer.clear();
@@ -59,14 +60,14 @@ public class TESTPacket extends KLALBPacket {
dataBuffer.flip(); dataBuffer.flip();
} }
public TESTPacket(ByteBuffer bb) { public TESTNPacket(ByteBuffer bb) {
super(bb,HEADER_LENGTH); super(bb,HEADER_LENGTH);
} }
@Override @Override
public String toString() { 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; package org.kne.cloud.network.srv6;
public interface DijkstraAlgorithm extends Runnable{ 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 setGraph(long[][]pointers,long[][]heap,long startPoint) ;
public void run(); public void run();
public long[] getDirection(); public long[] getDirection();
@@ -14,14 +14,21 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public static final int PADN=4; public static final int PADN=4;
public static final int HMAC=5; public static final int HMAC=5;
public static final int SEQS=7; public static final int SEQS=7;
public static final int ACKSEQS=8;
private int headerLength=2;
public int getHeaderLength() {
return headerLength;
}
private boolean isDefault; private boolean isDefault;
protected volatile ByteBuffer header; protected volatile ByteBuffer header;
private ByteBuffer data; private ByteBuffer data;
public IPv6SegmentRoutingTLV(ByteBuffer header ) { public IPv6SegmentRoutingTLV(ByteBuffer header ) {
this(header,true); this(header,true);
} }
@@ -32,7 +39,10 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) { public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
super(); super();
this.header = header; this.header = header;
if(isDefault&&(getType()!=PAD1)) { this.isDefault=isDefault;
if(getType()==PAD1)
headerLength=1;
if(isDefault&&(headerLength>1)) {
data=ByteBuffer.allocate(512); data=ByteBuffer.allocate(512);
} }
} }
@@ -42,17 +52,19 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public IPv6SegmentRoutingTLV(int type,boolean isDefault) { public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
super(); super();
this.header=ByteBuffer.allocate(2); this.header=ByteBuffer.allocate(2);
this.isDefault=isDefault;
header.put((byte) type); header.put((byte) type);
if(isDefault&&(type!=PAD1)) { if(type==PAD1) {
headerLength=1;
}
if(isDefault&&(headerLength>1)) {
data=ByteBuffer.allocate(512); data=ByteBuffer.allocate(512);
} }
} }
@Override @Override
public long getLength() { public long getLength() {
if(getType()==PAD1) return headerLength+(isDefault?data.limit():0);
return 1;
return header.limit()+(isDefault?data.limit():0);
} }
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException { public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
@@ -74,6 +86,14 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
rtlv=new PADNSegmentRoutingTLV(bbf); rtlv=new PADNSegmentRoutingTLV(bbf);
rtlv.readFromChannel(din); rtlv.readFromChannel(din);
return rtlv; 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: default:
rtlv=new IPv6SegmentRoutingTLV(bbf); rtlv=new IPv6SegmentRoutingTLV(bbf);
rtlv.readFromChannel(din); rtlv.readFromChannel(din);
@@ -84,26 +104,26 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
tlv.writeToChannel(dto); tlv.writeToChannel(dto);
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
if(isDefault&&(getType()!=PAD1)) { if(isDefault&&(headerLength>1)) {
setDataLength(data.limit()); setDataLength(data.limit());
} }
header.limit(headerLength);
dto.write(header.slice(0,header.limit())); dto.write(header.slice(0,header.limit()));
if(isDefault&&(getType()!=PAD1)) { if(isDefault&&(headerLength>1)) {
dto.write(data.slice(0, data.limit())); dto.write(data.slice(0, data.limit()));
} }
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
header.limit(1); header.limit(1);
while (header.hasRemaining()) { while (header.hasRemaining()) {
if (din.read(header) == -1) { if (din.read(header) == -1) {
throw new EOFException(); throw new EOFException();
} }
} }
int type=getType(); if(headerLength>1) {
if(type!=PAD1) {
header.limit(2); header.limit(2);
while (header.hasRemaining()) { while (header.hasRemaining()) {
if (din.read(header) == -1) { if (din.read(header) == -1) {
@@ -113,7 +133,7 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
} }
header.flip(); header.flip();
if(isDefault&&(getType()!=PAD1)) { if(isDefault&&(headerLength>1)) {
data.clear(); data.clear();
data.limit(getDataLength()); data.limit(getDataLength());
while(data.hasRemaining()){ 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.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup; import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor; 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.DelayMonitorData;
import org.kne.cloud.network.monitor.MonitorData; import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl; import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData; import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl; import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.scanner.InetAddressRange; 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{ public class KLALBRoutingProtocol extends Thread{
private static final boolean debug = false; private static final boolean debug = false;
private RouterInfo selfRouterInfo;
private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>(); private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
private volatile Map<Inet6Address,Long>addresses; 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_PORT=1001;
public static final int DEFAULT_PROTOCOL_NUMBER=252;
public static final long HOTSOPT_TIMEOUT = 1000000000; public static final long HOTSOPT_TIMEOUT = 1000000000;
public static final int HOTSOPT_REPORT_INTERVAL = 100000000; public static final int HOTSOPT_REPORT_INTERVAL = 100000000;
@@ -63,60 +78,59 @@ public class KLALBRoutingProtocol extends Thread{
this.router=router; this.router=router;
} }
private ReentrantLock sendlock=new ReentrantLock(); //private ReentrantLock sendlock=new ReentrantLock();
private long floodTimer=System.nanoTime(); private long floodTimer=System.nanoTime();
private long floodTimer2=System.nanoTime(); private long floodTimer2=System.nanoTime();
private long requestTimer=System.nanoTime();
@Override @Override
public void run() { public void run() {
Thread.currentThread().setName("KLALB路由协议接收线程"); Thread.currentThread().setName("KLALB路由协议接收线程");
getSelfRouterInfo(); getSelfRouterInfo();
DatagramSocket ds = null; KLALBVirtualRawSocket ds = null;
try{ try{
ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) ); ds=new KLALBVirtualRawSocket(router,router.getLocator().getAddress(), DEFAULT_PROTOCOL_NUMBER);
DatagramSocket ds2=ds; KLALBVirtualRawSocket ds2=ds;
new Thread(()->{ new Thread(()->{
Thread.currentThread().setName("KLALB路由协议接收线程"); Thread.currentThread().setName("KLALB路由协议接收线程");
while(true) { while(true) {
try { try {
/*List<NetworkLink>links=router.getLinkTabel(); selfRouterInfo = getSelfRouterInfo();
Object[] nls=links.toArray(); RouterInfo oslf=netmap.put(selfRouterInfo.getLocator().getAddress(), selfRouterInfo);
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);
noticeUpdate(); noticeUpdate();
if(oslf==null||(!slf.equals(oslf))) { /*if(oslf==null||(!selfRouterInfo.equals(oslf))) {
//System.out.println("change:"+oslf+"\n"+slf);
long cur=System.nanoTime(); long cur=System.nanoTime();
if(cur-floodTimer2>5000000000L) { if(cur-floodTimer2>5000000000L) {
//System.out.println("update10"); //System.out.println("update10");
floodTimer2=cur; floodTimer2=cur;
floodPacket(ds2, null, new RouterInfoPacket(slf,true)); floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
} }
}else { }else {
long cur=System.nanoTime(); long cur=System.nanoTime();
if(cur-floodTimer>60000000000L) { if(cur-floodTimer>60000000000L) {
//System.out.println("update60"); //System.out.println("update60");
floodTimer=cur; 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();) { for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = netmap.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next(); Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next();
RouterInfo val=type.getValue(); RouterInfo val=type.getValue();
@@ -124,7 +138,7 @@ public class KLALBRoutingProtocol extends Thread{
iterator.remove(); iterator.remove();
noticeUpdate(); noticeUpdate();
} }
Set<NeighborInfo> ads=val.getNeighborAddresses(); /*List<NeighborInfo> ads=val.getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) { for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) {
Inet6Address address=iterator2.next().getLocator().getAddress(); Inet6Address address=iterator2.next().getLocator().getAddress();
//System.out.println(address); //System.out.println(address);
@@ -132,35 +146,37 @@ public class KLALBRoutingProtocol extends Thread{
requestSet.add(address); requestSet.add(address);
} }
} }*/
} }
computeShortestPathIfUpdated(); computeShortestPathIfUpdated();
/*long cur2=System.nanoTime();
if(cur2-requestTimer>1000000000L) {
requestTimer=cur2;
for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) { for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next(); Inet6Address inet6Address = (Inet6Address) iterator.next();
byte[]to=new byte[] {0};
DatagramPacket dgp=new DatagramPacket(to,to.length); writePacket(ds2, new RouterInfoRequestPacket( ), new InetSocketAddress(inet6Address, DEFAULT_PORT));
dgp.setAddress(inet6Address);
dgp.setPort(DEFAULT_PORT);
if(debug) if(debug)
System.out.println("Request:"+inet6Address); 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();) { for (Iterator<Entry<Inet6Address, HotspotAddressTimer>> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next(); Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next();
if(type.getValue().checkReportTime()) { if(type.getValue().checkReportTime()) {
//System.out.println("hotspot address:"+type.getKey()); //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()) { if(type.getValue().checkTimeOut()) {
iterator.remove(); iterator.remove();
@@ -193,8 +209,16 @@ public class KLALBRoutingProtocol extends Thread{
switch(kp.getType()) { switch(kp.getType()) {
case KLALBRoutingProtocolPacket.RINFO_REQ: case KLALBRoutingProtocolPacket.RINFO_REQ:
RouterInfo rifr=netmap.get(router.getLocator().getAddress()); RouterInfo rifr=netmap.get(router.getLocator().getAddress());
if(rifr!=null) if(debug)
writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress()); 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; break;
case KLALBRoutingProtocolPacket.RINFO: 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(); List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray(); Object[] nls=links.toArray();
for(int i=0;i<nls.length;i++) { for(int i=0;i<nls.length;i++) {
@@ -248,27 +273,31 @@ public class KLALBRoutingProtocol extends Thread{
Neighbor addresses = (Neighbor) iteratorx.next(); Neighbor addresses = (Neighbor) iteratorx.next();
InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT); InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT);
if(!isa.equals(except)) { 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); ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt); KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt);
byte[]to=bos.toByteArray(); byte[]to=bos.toByteArray();
DatagramPacket dgpx=new DatagramPacket(to,to.length); DatagramPacket dgpx=new DatagramPacket(to,to.length);
dgpx.setSocketAddress(dest); dgpx.setSocketAddress(dest);
sendlock.lock();
try { try {
ds.send(dgpx); ds2.send(dgpx);
}catch(BindException e) { }catch(BindException e) {
e.printStackTrace(); e.printStackTrace();
System.err.println("Cannot assign:"+dest); System.err.println("Cannot assign:"+dest);
}finally {
sendlock.unlock();
} }
} }
@@ -329,47 +358,51 @@ public class KLALBRoutingProtocol extends Thread{
return; return;
} }
Set<Entry<Inet6Address, RouterInfo>> s=netmap.entrySet(); 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; long number=0;
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = s.iterator(); iterator.hasNext();) { for(Entry<Inet6Address, RouterInfo> entry:s) {
Entry<Inet6Address, RouterInfo> entry = (Entry<Inet6Address, RouterInfo>) iterator.next();
if(!airs.containsKey(entry.getKey())) { if(!airs.containsKey(entry.getKey())) {
airs.put(entry.getKey(),number); airs.put(entry.getKey(),number);
rias.add( entry.getKey()); rias.add( entry.getKey());
number++; number++;
} }
Set<NeighborInfo> ni= entry.getValue().getNeighborAddresses(); List<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ni.iterator(); iterator2.hasNext();) { for(NeighborInfo neighborInfo :ni) {
NeighborInfo neighborInfo = (NeighborInfo) iterator2.next();
Inet6Address ias2=neighborInfo.getLocator().getAddress(); Inet6Address ias2=neighborInfo.getLocator().getAddress();
if(!airs.containsKey(ias2)) { if(!airs.containsKey(ias2)) {
airs.put(ias2,number); airs.put(ias2,number);
rias.add( ias2); rias.add( ias2);
number++; number++;
} }
Set<LinkDirection>lp1=paths.get(entry.getKey()); List<LinkDirection>lp1=paths.get(entry.getKey());
if(lp1==null) { 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) { if(lp2==null) {
paths.put(ias2, lp2=new HashSet<>()); 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[][]pointers=new long[(int) airs.size()][2];
long heappos=0; long heappos=0;
long linknumber=0; long linknumber=0;
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) { for(Entry<Inet6Address, List<LinkDirection>> entry:paths.entrySet()) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next(); /*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(); linknumber+=entry.getValue().size();
} }
long[][]heap=new long[(int) (linknumber)][2]; long[][]heap=new long[(int) (linknumber)][2];
@@ -377,12 +410,16 @@ public class KLALBRoutingProtocol extends Thread{
long heapindex=0; long heapindex=0;
pointers[(int) i][0]=heappos; pointers[(int) i][0]=heappos;
InetAddress ia=rias.get((int) i); InetAddress ia=rias.get((int) i);
Set<LinkDirection>lks=paths.get(ia); List<LinkDirection>lks=paths.get(ia);
if(lks!=null) if(lks!=null)
for(LinkDirection linkPath:lks) {
/*
for (Iterator<LinkDirection> iterator = lks.iterator(); iterator.hasNext();) { 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)][0]=airs.get(linkPath.getToLocator());
heap[(int) (heappos+heapindex)][1]=linkPath.getWeight(); heap[(int) (heappos+heapindex)][1]=linkPath.getWeight();
//heap[(int) (heappos+heapindex)][2]=linkPath.get
// heap[(int) (heappos+heapindex)][3]=0;
heapindex++; heapindex++;
} }
@@ -391,6 +428,8 @@ public class KLALBRoutingProtocol extends Thread{
pointers[(int) i][1]=heapindex; pointers[(int) i][1]=heapindex;
} }
algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress())); algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress()));
algorithm.run(); algorithm.run();
directions=new NetmapDirections(algorithm.getDirection(), rias, airs); directions=new NetmapDirections(algorithm.getDirection(), rias, airs);
@@ -407,12 +446,12 @@ public class KLALBRoutingProtocol extends Thread{
private Inet6Address fromLocator; private Inet6Address fromLocator;
private Inet6Address toLocator; private Inet6Address toLocator;
private long delay; private long delay;
private long delayMin;
private long speed; private long speed;
public long getSpeed() { public long getSpeed() {
return speed; return speed;
} }
private long bandwidth; private long bandwidth;
private long usedBandwidth=0;
public Inet6AddressGroup getFromAddress() { public Inet6AddressGroup getFromAddress() {
return fromAddress; return fromAddress;
} }
@@ -425,22 +464,28 @@ public class KLALBRoutingProtocol extends Thread{
public long getBandwidth() { public long getBandwidth() {
return bandwidth; return bandwidth;
} }
public long getDelayMin() {
return delayMin;
}
public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator, 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(); super();
this.fromAddress = fromAddress; this.fromAddress = fromAddress;
this.toAddress = toAddress; this.toAddress = toAddress;
this.fromLocator = fromLocator; this.fromLocator = fromLocator;
this.toLocator = toLocator; this.toLocator = toLocator;
this.delay = delay; this.delay = delay;
this.speed=speed; this.delayMin = delayMin;
this.speed = speed;
this.bandwidth = bandwidth; this.bandwidth = bandwidth;
} }
@Override @Override
public String toString() { public String toString() {
return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator=" return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator="
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed + fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", delayMin=" + delayMin
+ ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]"; + ", speed=" + speed + ", bandwidth=" + bandwidth + "]";
} }
public Inet6Address getFromLocator() { public Inet6Address getFromLocator() {
return fromLocator; return fromLocator;
@@ -470,8 +515,7 @@ public class KLALBRoutingProtocol extends Thread{
private RouterInfo getSelfRouterInfo() { private RouterInfo getSelfRouterInfo() {
List<IPv6NetworkLink>links=router.getLinkTabel(); List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray(); Object[] nls=links.toArray();
RouterInfo ri=new RouterInfo(System.currentTimeMillis()); RouterInfo ri=new RouterInfo(System.currentTimeMillis(),router.getLocator(),router.getASN());
ri.setLocator(router.getLocator());
for(int i=0;i<nls.length;i++) { for(int i=0;i<nls.length;i++) {
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i]; IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
if((!nl.isLoopBack())&&nl.isUp()) { if((!nl.isLoopBack())&&nl.isUp()) {
@@ -480,6 +524,8 @@ public class KLALBRoutingProtocol extends Thread{
Neighbor addresses = (Neighbor) iteratorx.next(); Neighbor addresses = (Neighbor) iteratorx.next();
long updelay=10000000000L; long updelay=10000000000L;
long downdelay=10000000000L; long downdelay=10000000000L;
long updelayMin=10000000000L;
long downdelayMin=10000000000L;
long uploadspeed=1024L*1024; long uploadspeed=1024L*1024;
long downloadspeed=1024L*1024; long downloadspeed=1024L*1024;
long uploadspeedmax=1024L*1024; long uploadspeedmax=1024L*1024;
@@ -489,6 +535,11 @@ public class KLALBRoutingProtocol extends Thread{
if(md instanceof DelayMonitorData) { if(md instanceof DelayMonitorData) {
updelay=((DelayMonitorData) md).getOutDelay(); updelay=((DelayMonitorData) md).getOutDelay();
downdelay=((DelayMonitorData) md).getInDelay(); downdelay=((DelayMonitorData) md).getInDelay();
if(md instanceof SpeedAndTrafficAndDelayMonitorDataImpl) {
updelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getOutDelayMin();
downdelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getInDelayMin();
}
} }
if(md instanceof SpeedAndTrafficMonitorData) { if(md instanceof SpeedAndTrafficMonitorData) {
uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed(); 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() { public Map<Inet6Address, Long> getAddresses() {
return addresses; return addresses;
} }
public Map<Inet6Address, Set<LinkDirection>> getPaths() { public Map<Inet6Address, List<LinkDirection>> getPaths() {
return paths; return paths;
} }
public List<Inet6Address> createSegmentList(Inet6Address dest) { public List<Inet6Address> createSegmentList(Inet6Address dest) {
@@ -564,12 +617,41 @@ public class KLALBRoutingProtocol extends Thread{
private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>(); private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>();
public void putHotspotAddress(Inet6Address sourceAddress) { public void putHotspotAddress(Inet6Address sourceAddress) {
if(true) {
HotspotAddressTimer hat=hotspots.get(sourceAddress); HotspotAddressTimer hat=hotspots.get(sourceAddress);
if(hat==null) { if(hat==null) {
hotspots.put(sourceAddress, new HotspotAddressTimer()); hotspots.put(sourceAddress, new HotspotAddressTimer());
}else { }else {
hat.refreshTimeout(); 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) { public KLALBRoutingProtocolPacket(int type) {
super(); super();
header=NetworkPacket.databufferpool_40.borrow(); header=NetworkPacket.bufferAllocator.allocate(40);
header.put((byte) type); header.put((byte) type);
} }
@Override @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(); sndtime=System.nanoTime();
dto.write(header.slice(0, (int) getHeaderSize())); dto.write(header.slice(0, (int) getHeaderSize()));
} }
@@ -59,7 +59,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
return false; return false;
} }
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException { public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
rcvtime=System.nanoTime(); rcvtime=System.nanoTime();
//System.out.println(this+" "+getHeaderSize()); //System.out.println(this+" "+getHeaderSize());
header.limit((int) getHeaderSize()); header.limit((int) getHeaderSize());
@@ -89,12 +89,6 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
return header; 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 { public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
return readKLALBPacketFromChannel(Channels.newChannel(in)); return readKLALBPacketFromChannel(Channels.newChannel(in));
@@ -102,7 +96,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException { public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
while(true) { while(true) {
ByteBuffer bb=databufferpool_40.borrow(); ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
bb.limit(1); bb.limit(1);
while(bb.hasRemaining()){ while(bb.hasRemaining()){
if(in.read(bb)==-1) { if(in.read(bb)==-1) {
@@ -11,6 +11,7 @@ import java.net.Inet6Address;
import java.util.Objects; import java.util.Objects;
import org.kne.cloud.network.ipv6.Inet6AddressGroup; import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
public class NeighborInfo implements Serializable { public class NeighborInfo implements Serializable {
@Override @Override
@@ -26,13 +27,16 @@ public class NeighborInfo implements Serializable {
private Inet6AddressGroup local; private Inet6AddressGroup local;
private Inet6AddressGroup neighbor; private Inet6AddressGroup neighbor;
private Inet6AddressGroup locator; 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(); super();
this.local=local; this.local=local;
this.neighbor = neighbor; this.neighbor = neighbor;
this.locator=locator; this.locator=locator;
this.uploadDelay = uploadDelay; this.uploadDelay = uploadDelay;
this.downloadDelay = downloadDelay; this.downloadDelay = downloadDelay;
this.uploadDelayMin = uploadDelayMin;
this.downloadDelayMin= downloadDelayMin;
this.uploadSpeed = uploadSpeed; this.uploadSpeed = uploadSpeed;
this.downloadSpeed = downloadSpeed; this.downloadSpeed = downloadSpeed;
this.uploadSpeedMax=uploadspeedmax; this.uploadSpeedMax=uploadspeedmax;
@@ -40,12 +44,24 @@ public class NeighborInfo implements Serializable {
} }
public NeighborInfo() { public NeighborInfo() {
} }
private long uploadDelay; private long uploadDelay;
private long downloadDelay; private long downloadDelay;
private long uploadDelayMin;
private long downloadDelayMin;
private long uploadSpeed; private long uploadSpeed;
private long downloadSpeed; private long downloadSpeed;
private long uploadSpeedMax; private long uploadSpeedMax;
private long downloadSpeedMax; private long downloadSpeedMax;
public void setContext(Neighbor context) {
this.context = context;
}
public Neighbor getContext() {
return context;
}
public Inet6AddressGroup getNeighbor() { public Inet6AddressGroup getNeighbor() {
return neighbor; return neighbor;
} }
@@ -100,6 +116,7 @@ public class NeighborInfo implements Serializable {
public void setLocator(Inet6AddressGroup locator) { public void setLocator(Inet6AddressGroup locator) {
this.locator = locator; this.locator = locator;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(local, locator, neighbor); return Objects.hash(local, locator, neighbor);
@@ -122,6 +139,8 @@ public class NeighborInfo implements Serializable {
locator.writeToStream(out); locator.writeToStream(out);
out.writeLong(uploadDelay); out.writeLong(uploadDelay);
out.writeLong(downloadDelay); out.writeLong(downloadDelay);
out.writeLong(uploadDelayMin);
out.writeLong(downloadDelayMin);
out.writeLong(uploadSpeed); out.writeLong(uploadSpeed);
out.writeLong(downloadSpeed); out.writeLong(downloadSpeed);
out.writeLong(uploadSpeedMax); out.writeLong(uploadSpeedMax);
@@ -134,9 +153,17 @@ public class NeighborInfo implements Serializable {
locator=new Inet6AddressGroup(in); locator=new Inet6AddressGroup(in);
uploadDelay=in.readLong(); uploadDelay=in.readLong();
downloadDelay=in.readLong(); downloadDelay=in.readLong();
uploadDelayMin=in.readLong();
downloadDelayMin=in.readLong();
uploadSpeed=in.readLong(); uploadSpeed=in.readLong();
downloadSpeed=in.readLong(); downloadSpeed=in.readLong();
uploadSpeedMax=in.readLong(); uploadSpeedMax=in.readLong();
downloadSpeedMax=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 class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public PAD1SegmentRoutingTLV(int type) { public PAD1SegmentRoutingTLV() {
super(type); super(IPv6SegmentRoutingTLV.PAD1);
} }
public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) { public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) {
@@ -11,19 +11,20 @@ public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
super(klalbHeader); super(klalbHeader);
} }
public PADNSegmentRoutingTLV(int type) { public PADNSegmentRoutingTLV(int dataLength) {
super(type); super(IPv6SegmentRoutingTLV.PADN);
getData().limit(dataLength);
} }
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto); super.writeToChannel(dto);
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length); super.readFromChannel(din, length);
} }
+19 -7
View File
@@ -30,12 +30,20 @@ public class RouterInfo implements Serializable{
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Inet6AddressGroup locator; private Inet6AddressGroup locator;
private long asn;
public Inet6AddressGroup getLocator() { public Inet6AddressGroup getLocator() {
return locator; return locator;
} }
public void setLocator(Inet6AddressGroup locator) { public void setLocator(Inet6AddressGroup locator) {
this.locator = locator; this.locator = locator;
} }
public long getAsn() {
return asn;
}
public void setAsn(long asn) {
this.asn = asn;
}
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(locator, neighborAddresses); return Objects.hash(locator, neighborAddresses);
@@ -51,7 +59,7 @@ public class RouterInfo implements Serializable{
RouterInfo other = (RouterInfo) obj; RouterInfo other = (RouterInfo) obj;
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses); 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; private long createTime;
@@ -59,7 +67,7 @@ public class RouterInfo implements Serializable{
return createTime; return createTime;
} }
private static final long INFO_UPDATETIME=10000000000L; 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(); private long putTime=System.nanoTime();
public boolean checkUpdateTime() { public boolean checkUpdateTime() {
return System.nanoTime()-putTime>INFO_UPDATETIME; return System.nanoTime()-putTime>INFO_UPDATETIME;
@@ -74,21 +82,24 @@ public class RouterInfo implements Serializable{
return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime
+ "]"; + "]";
} }
public Set<NeighborInfo> getNeighborAddresses() { public List<NeighborInfo> getNeighborAddresses() {
return neighborAddresses; return neighborAddresses;
} }
public RouterInfo( long createTime) { public RouterInfo( long createTime,Inet6AddressGroup locator,long asn) {
this.createTime = createTime; this.createTime = createTime;
this.locator=locator;
this.asn=asn;
} }
public RouterInfo() { public RouterInfo() {
} }
public void writeToStream(DataOutputStream out) throws IOException { public void writeToStream(DataOutputStream out) throws IOException {
locator.writeToStream(out); locator.writeToStream(out);
out.writeLong(asn);
out.writeLong(createTime); out.writeLong(createTime);
out.writeInt(neighborAddresses.size()); out.writeInt(neighborAddresses.size());
for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) { for( NeighborInfo neighborInfo :neighborAddresses) {
NeighborInfo neighborInfo = (NeighborInfo) iterator.next();
neighborInfo.writeToStream(out); neighborInfo.writeToStream(out);
} }
} }
@@ -101,9 +112,10 @@ public class RouterInfo implements Serializable{
} }
public void readFromStream(DataInputStream in) throws IOException { public void readFromStream(DataInputStream in) throws IOException {
locator=new Inet6AddressGroup(in); locator=new Inet6AddressGroup(in);
asn=in.readLong();
createTime=in.readLong(); createTime=in.readLong();
int size=in.readInt(); int size=in.readInt();
neighborAddresses=new HashSet<>(size); neighborAddresses=new ArrayList<>(size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
NeighborInfo nif=new NeighborInfo(); NeighborInfo nif=new NeighborInfo();
nif.readFromStream(in); nif.readFromStream(in);
@@ -24,9 +24,10 @@ import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{
public RouterInfoPacket(RouterInfo routerInfo, boolean flood) { public RouterInfoPacket(RouterInfo routerInfo, boolean flood,long asn) {
super(RINFO); super(RINFO);
getHeader().put(1,(byte) (flood?1:0)); getHeader().put(1,(byte) (flood?1:0));
getHeader().putLong(2,asn);
this.rinfo=routerInfo; this.rinfo=routerInfo;
} }
protected RouterInfoPacket(ByteBuffer bb) { protected RouterInfoPacket(ByteBuffer bb) {
@@ -39,12 +40,16 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
return (getHeader().get(1)&1)==1; return (getHeader().get(1)&1)==1;
} }
public long getASN() {
return getHeader().getLong(2);
}
public RouterInfo getRinfo() { public RouterInfo getRinfo() {
return rinfo; return rinfo;
} }
@Override @Override
protected long getHeaderSize() { protected long getHeaderSize() {
return super.getHeaderSize()+1; return super.getHeaderSize()+9;
} }
@Override @Override
public long getLength() { public long getLength() {
@@ -60,12 +65,12 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
@Override @Override
protected void writeToChannel(WritableByteChannel dto) throws IOException { public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto); super.writeToChannel(dto);
rinfo.writeToChannel(dto); rinfo.writeToChannel(dto);
} }
@Override @Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException { public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length); super.readFromChannel(din, length);
rinfo=new RouterInfo(); rinfo=new RouterInfo();
rinfo.readFromChannel(din, length); 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