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"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/graalvm-jdk-23.0.1+11.1">
<attributes>
<attribute name="module" value="true"/>
@@ -15,11 +16,13 @@
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-propertiesbased-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-packetfactory-static-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/pcap4j-sample-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/JavaTUN.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-javadoc.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-sources.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-2.0.9-tests.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/KNElib"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0.jar" sourcepath="lib/disruptor-4.0.0-sources.jar"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0-javadoc.jar"/>
<classpathentry kind="lib" path="lib/disruptor-4.0.0-sources.jar"/>
<classpathentry kind="lib" path="lib/JavaTUN.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
BIN
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",
"UDPListen" : "{UDP}0.0.0.0:4572",
"VirtualSocketName" : "KLALB_Stream",
"LineTable":["cn-he-plc-2.ofalias.com:4572"]
"LineTable":["07f4acdef99b.ofalias.net:4572","{UDP}07f4acdef99b.ofalias.net:4572"]
},
{"Type":"SocketBridge" ,
"Listen" : "0.0.0.0:4572",
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.concurrent.ArrayBlockingQueue;
@@ -0,0 +1,133 @@
package org.kne.cloud.network;
import java.lang.ref.Cleaner;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import org.kne.debug.TimeDebugger;
public class ByteBufferAllocator {
private List<ByteBufferPool> bbfps=new ArrayList<>();
private ByteBufferPool[]bbfpsarr;
private ReferenceQueue<ByteBuffer> refq=new ReferenceQueue<>();
private boolean isDirect;
public ByteBufferAllocator(boolean isDirect) {
this.isDirect=isDirect;
int i=1;
int maxi=0;
int mps=16;
for (int j = 0; j < 18; j++) {
int count=100;
mps+=count;
bbfps.add(new ByteBufferPool(mps, i,isDirect));
maxi=i;
i<<=1;
}
bbfpsarr=new ByteBufferPool[maxi];
for (int j = 0; j < bbfpsarr.length; j++) {
bbfpsarr[j]=getByteBufferPool(j);
}
Thread t= new Thread(()->{
while(true) {
try {
Reference<? extends ByteBuffer> ref;
ref = refq.remove();
if(ref!=null) {
ref.clear();
}
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
});
t.setPriority(Thread.MAX_PRIORITY-1);
t.start();
}
public ByteBuffer allocate(int capacity) {
if(true) {
return allocateHeap(capacity);
}
//new Exception().printStackTrace();
ByteBufferPool bbfp=bbfpsarr[capacity];
ByteBuffer bbf=null;
try {
bbf=bbfp.borrow();
}catch(OutOfMemoryError err) {
System.gc();
Thread.yield();
bbf=bbfp.borrow();
}
ByteBuffer bbfs=bbf.slice(0, capacity);
new ByteBufferPhantomReference(bbfs,refq,bbf,bbfp);
return bbfs;
}
private static ByteBuffer allocateHeap(int capacity) {
return ByteBuffer.wrap(new byte[capacity]);
}
private ByteBufferPool getByteBufferPool(int capacity) {
int elen=0;
for (int i = 0; i < bbfps.size(); i++) {
ByteBufferPool bfp=bbfps.get(i);
if(capacity<=(elen= bfp.getLength())) {
return bfp;
}
}
throw new RuntimeException("capacity:"+capacity+">"+elen);
}
private static class ByteBufferPhantomReference extends PhantomReference<ByteBuffer>{
private static AtomicReference<ByteBufferPhantomReference> first=new AtomicReference<>(null);
private AtomicReference<ByteBufferPhantomReference> next=new AtomicReference<>(null);
private AtomicReference<ByteBufferPhantomReference> prev=new AtomicReference<>(null);
private ByteBuffer father;
private ByteBufferPool pool;
public ByteBufferPhantomReference(ByteBuffer referent, ReferenceQueue<? super ByteBuffer> q,ByteBuffer father,ByteBufferPool pool) {
super(referent, q);
this.father=father;
this.pool=pool;
insert();
}
private void insert() {
ByteBufferPhantomReference refn= first.getAndSet(this);
if(refn!=null) {
next.set(refn);
refn.prev.set(this);
}
}
private void remove() {
ByteBufferPhantomReference prevn= prev.getAndSet(null);
ByteBufferPhantomReference nextn=next.getAndSet(null);
if(prevn!=null)
prevn.next.set(nextn);
if(nextn!=null)
nextn.prev.set(prevn);
}
@Override
public void clear() {
//System.out.println("clear");
pool.back(father);
remove();
super.clear();
}
}
}
@@ -0,0 +1,79 @@
package org.kne.cloud.network;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.concurrent.SpinLock;
import org.kne.debug.TimeDebugger;
public class ByteBufferPool {
private AtomicReferenceArray< ByteBuffer> rec;
private volatile AtomicInteger pos=new AtomicInteger( 0);
//private Lock lock=new SpinLock();
private int maxcount;
private int length;
private int mcj;
private boolean direct;
public ByteBufferPool(int maxcount, int length,boolean direct) {
super();
this.maxcount = maxcount;
this.length = length;
this.direct=direct;
rec=new AtomicReferenceArray<ByteBuffer>(maxcount);
mcj= rec.length()-1;
}
public ByteBufferPool(int maxcount, int length) {
this(maxcount, length, true);
}
public void back(ByteBuffer b) {
if(b.capacity()!=length)
throw new IllegalArgumentException("wrong length");
b.clear();
if(pos.get()<=mcj) {
int d=pos.getAndIncrement();
if(d>mcj)
d=mcj;
if(d<0)
d=0;
rec.compareAndSet(d,null,b);
}
}
public ByteBuffer borrow() {
ByteBuffer b=null;
if(pos.get()>0) {
int d=pos.decrementAndGet();
if(d>mcj)
d=mcj;
if(d<0)
d=0;
b=rec.getAndSet(d,null);
}
if(b==null) {
if(direct)
b=ByteBuffer.allocateDirect(length);
else
b=ByteBuffer.allocate(length);
}
return b;
}
public int getMaxCount() {
return maxcount;
}
public int getLength() {
return length;
}
}
@@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.locks.LockSupport;
import org.kne.cloud.network.klalb.ByteArrayPool;
import org.kne.cloud.network.klalb.DATATPacket;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
@@ -14,6 +14,7 @@ import java.net.NetworkInterface;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
@@ -31,6 +32,15 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
private List<MultipurposeSocketAddress> msas;
private volatile Consumer<MultipurposeSocketAddress> con;
private long timeInterval;
public long getTimeInterval() {
return timeInterval;
}
public void setTimeInterval(long timeInterval) {
this.timeInterval = timeInterval;
}
public NetworkInterface getNinterface() {
return ninterface;
@@ -53,13 +63,14 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
}
public IPMulticastDiscovery(InetSocketAddress bind, InetSocketAddress group, NetworkInterface ninterface,
List<MultipurposeSocketAddress> msas) throws IOException {
List<MultipurposeSocketAddress> msas,long timeInterval) throws IOException {
soc = new MulticastSocket(bind);
soc.joinGroup(group, ninterface);
this.bind = bind;
this.group = group;
this.ninterface = ninterface;
this.msas = msas;
this.timeInterval=timeInterval;
}
@Override
@@ -104,7 +115,7 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
}
Thread.sleep(10000L);
Thread.sleep(timeInterval);
}
} catch (IOException e) {
e.printStackTrace();
@@ -133,11 +144,13 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
dis.close();
MultipurposeSocketAddress mpsa = new MultipurposeSocketAddress(type, dp.getAddress().getHostAddress(),
port);
try {
InetAddress mpsai=mpsa.getInetAddress();
//System.out.println(mpsa);
Enumeration<InetAddress> ei = ninterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if (inetAddress.equals(mpsa.getInetAddress())) {
if (inetAddress.equals(mpsai)) {
continue loop;
}
}
@@ -145,13 +158,16 @@ public class IPMulticastDiscovery extends Thread implements Closeable, AutoClose
if (con != null) {
con.accept(mpsa);
}
}catch(UnknownHostException e) {
}
}
} catch (IOException e) {
System.out.println(bind + " " + group + " " + ninterface);
e.printStackTrace();
} finally {
try {
close();
} catch (IOException e) {
e.printStackTrace();
+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.ReentrantLock;
import org.kne.cloud.network.klalb.ByteArrayPool;
import org.kne.cloud.network.klalb.ByteBufferPool;
import org.kne.cloud.network.klalb.KLALBPacket;
import org.kne.debug.TimeDebugger;
public abstract class NetworkPacket implements Comparable<NetworkPacket>{
private static final boolean debugPassport=false;
public static final ByteBufferAllocator bufferAllocator=new ByteBufferAllocator(true);
public static final ByteArrayPool dataarraypool_65535=new ByteArrayPool(10000, 65535);
//public static final ByteArrayPool dataarraypool_65535=new ByteArrayPool(10000, 65535);
public static final ByteBufferPool databufferpool_65535=new ByteBufferPool(10000, 65535,false);
//public static final ByteBufferPool databufferpool_65535=new ByteBufferPool(10000, 65535,false);
public static final ByteBufferPool databufferpool_2048=new ByteBufferPool(10000, 2048,false);
//public static final ByteBufferPool databufferpool_2048=new ByteBufferPool(10000, 2048,false);
public static final ByteBufferPool databufferpool_40=new ByteBufferPool(10000, 40,false);
//public static final ByteBufferPool databufferpool_40=new ByteBufferPool(10000, 40,false);
private TimeDebugger passport;
private final TimeDebugger passport;
{
if(debugPassport) {
passport=new TimeDebugger();
passport.putTime(getClass().getSimpleName()+ "_create");
}else {
passport=null;
}
}
public void putTimePassport(String label) {
public final void putTimePassport(String label) {
if(passport!=null) {
passport.putTime(label);
}
}
public void printPassport() {
public final void printPassport() {
if(passport!=null) {
passport.printWithTimeFilter(100000000L);
}
}
private volatile boolean disposeAfterSend=false;
public boolean isDisposeAfterSend() {
return disposeAfterSend;
}
public void setDisposeAfterSend(boolean disposeAfterSend) {
this.disposeAfterSend = disposeAfterSend;
}
private volatile boolean disposed=false;
private Lock disposeLock=new ReentrantLock();
public boolean isDisposed() {
return disposed;
}
public Lock getDisposeLock() {
return disposeLock;
}
public abstract long getLength();
public void dispose() {
/*disposeLock.lock();
try {*/
disposed=true;
/*}finally {
disposeLock.unlock();
}*/
}
public void lockAll() {
disposeLock.lock();
}
public boolean isSomeDisposed() {
return disposed;
}
public void unlockAll() {
disposeLock.unlock();
}
public long getPriority() {
return priority;
@@ -118,22 +83,14 @@ public abstract class NetworkPacket implements Comparable<NetworkPacket>{
}
}
public void disposeAll() {
dispose();
}
public void doDisposeAfterSend() {
if(isDisposeAfterSend())
dispose();
}
public void genseq() {
this.sendseq=seqgen.getAndIncrement();
}
protected abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
protected abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
protected void readFromChannel(ReadableByteChannel din) throws IOException{
public abstract void writeToChannel(WritableByteChannel dto) throws IOException ;
public abstract void readFromChannel(ReadableByteChannel din,long length) throws IOException;
public void readFromChannel(ReadableByteChannel din) throws IOException{
readFromChannel(din,-1);
}
protected abstract boolean needEndPosition();
+34 -13
View File
@@ -2,6 +2,7 @@ package org.kne.cloud.network;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.HashMap;
import java.util.Iterator;
@@ -11,14 +12,13 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.kne.cloud.network.klalb.ByteBufferPool;
public class PacketRebuilder {
public class PacketRebuilder implements ReadableByteChannel{
private static final ByteBufferPool bbfp=new ByteBufferPool(100, 65535);
private long timeout;
public PacketRebuilder(long timeout) {
public PacketRebuilder(ReadableByteChannel readableChannel,long timeout) {
this.timeout=timeout;
this.readableChannel=readableChannel;
}
@Override
@@ -58,10 +58,18 @@ public class PacketRebuilder {
}
public void read(ByteBuffer des,ReadableByteChannel rc) throws IOException {
while(true) {
private ReadableByteChannel readableChannel;
public ReadableByteChannel getReadableChannel() {
return readableChannel;
}
public int read(ByteBuffer des) throws IOException {
while(readableChannel.isOpen()) {
ByteBuffer cac=bbfp.borrow();
rc.read(cac);
readableChannel.read(cac);
cac.flip();
int ser=cac.getInt(0);
int countofpiece=cac.get(4);
@@ -75,12 +83,12 @@ public class PacketRebuilder {
ReceiveEntry reet=recvc.get(ser);
reet.getByteBuffers()[i]=cac;
if(reet.isFull()) {
rebuild(des ,reet.getByteBuffers());
int rez= rebuild(des ,reet.getByteBuffers());
for (int j = 0; j < reet.getByteBuffers().length; j++) {
bbfp.back(reet.getByteBuffers()[j]);
}
recvc.remove(ser);
return ;
return rez;
}
for (Iterator<Entry<Integer, ReceiveEntry>> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
Entry<Integer, ReceiveEntry> type = (Entry<Integer, ReceiveEntry>) iterator.next();
@@ -94,17 +102,30 @@ public class PacketRebuilder {
}
}
}
return -1;
}
public void rebuild(ByteBuffer des, ByteBuffer[]src) {
//System.out.print("Rebuild:");
public int rebuild(ByteBuffer des, ByteBuffer[]src) {
//StringBuilder sbd=new StringBuilder("Rebuild:");
int oldpos=des.position();
for (int i = 0; i < src.length; i++) {
src[i].getInt();
src[i].get();
src[i].get();
des.put(src[i]);
//System.out.print(src[i].limit()+" ");
// sbd.append(src[i].limit()+" ");
}
//System.out.println();
//System.out.println(sbd);
return des.position()-oldpos;
}
@Override
public boolean isOpen() {
return readableChannel.isOpen();
}
@Override
public void close() throws IOException {
readableChannel.close();
}
+22 -15
View File
@@ -6,14 +6,12 @@ import java.nio.channels.WritableByteChannel;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import org.kne.cloud.network.klalb.ByteBufferPool;
public class PacketSpliter {
private int splitSize;
private static final ByteBufferPool bbfp=new ByteBufferPool(100,65535,false);
private volatile int splitSize;
private AtomicInteger series=new AtomicInteger();
public PacketSpliter(int splitSize) {
private WritableByteChannel writableChannel;
public PacketSpliter(WritableByteChannel writableChannel,int splitSize) {
this.writableChannel=writableChannel;
this.splitSize=splitSize;
}
@@ -21,28 +19,37 @@ public class PacketSpliter {
return splitSize;
}
public WritableByteChannel getWritableChannel() {
return writableChannel;
}
public void setSplitSize(int splitSize) {
this.splitSize = splitSize;
}
@Override
public String toString() {
return "PacketSpliter [splitSize=" + splitSize + "]";
}
public void write(ByteBuffer bb,WritableByteChannel wc) throws IOException{
public void write(ByteBuffer bb) throws IOException{
ByteBuffer[]bbssp= split(bb);
for (int i = 0; i < bbssp.length; i++) {
wc.write(bbssp[i]);
bbfp.back(bbssp[i]);
writableChannel.write(bbssp[i]);
}
}
public ByteBuffer[] split(ByteBuffer bb) {
//System.out.print("Split:");
//StringBuilder sbd=new StringBuilder("Split:");
int splitSizex=splitSize;
int lenth=bb.limit();
int countofpiece=(lenth-1)/splitSize+1;
int remain=lenth%splitSize;
int countofpiece=(lenth-1)/splitSizex+1;
int remain=lenth%splitSizex;
ByteBuffer[]pieces=new ByteBuffer[countofpiece];
for (int i = 0; i < pieces.length; i++) {
pieces[i]=bbfp.borrow();
pieces[i]=NetworkPacket.bufferAllocator.allocate(splitSizex+6);
}
int sern=series.getAndIncrement();
for (int i = 0; i < pieces.length; i++) {
@@ -53,10 +60,10 @@ public class PacketSpliter {
bb.limit(Math.min(bb.remaining(), pieces[i].remaining())+bb.position());
pieces[i].put(bb);
bb.limit(bbl);
//System.out.print(pieces[i].position()+" ");
//sbd.append(pieces[i].position()+" ");
pieces[i].flip();
}
//System.out.println();
//System.out.println(sbd);
return pieces;
}
+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){
try {
SocketChannel soce=serverSocketChannel.accept();
ThreadTool.makePThreadIfSupport("端口监听线程",()->{
ThreadTool.makePThreadIfSupport("端口请求处理线程",()->{
if(con!=null) {
try {
con.accept(soce);
@@ -71,7 +71,7 @@ public class SocketChannelListener implements Closeable,AutoCloseable{
if(serverSocketChannel==null) {
throw new IOException(multipurposeSocketAddress.getType()+" unsupport SocketChannel");
}
new Thread(r).start();
ThreadTool.makeVThread("端口监听线程", r).start();
}
public void close() {
flag=false;
@@ -63,6 +63,7 @@ public class SpeedLimiter {
waitingtime.addAndGet(datasize*1000000000L/limitspeedx);
}
}
//用系统计时器的时刻相减得到经过的时间,与数据包除以限速值得到的应消耗的时间做对比,若时间还未到达发送下一个数据包的时机,则返回false
public boolean checkTransmit(long datasize) {
long limitspeedx=limitspeed;
if(limitspeedx<=0) {
+44 -1
View File
@@ -3,8 +3,8 @@ package org.kne.cloud.network;
import java.lang.reflect.Method;
public class ThreadTool {
public static boolean first=true;
public static boolean forceD=true;
public static boolean first=true;
public static Thread makeVThreadIfSupport(String name,Runnable r) {
if(forceD)
return new Thread(r, name);
@@ -64,4 +64,47 @@ public class ThreadTool {
rt.setDaemon(true);
return rt;
}
public static Thread makeVDaemonThread(String name, Runnable r) {
try { //return new Thread(r, name);
Class<?> c=Class.forName("java.lang.Thread");
Method m= c.getDeclaredMethod("ofVirtual", null);
Object o=m.invoke(null, null);
Class<?> cb=Class.forName("java.lang.Thread$Builder");
Method mn= cb.getDeclaredMethod("name", String.class);
mn.invoke(o, name);
Method mu= cb.getDeclaredMethod("unstarted", Runnable.class);
return (Thread) mu.invoke(o, r);
//return Thread.ofVirtual().name(name).unstarted(r);
}catch(Throwable e) {
//e.printStackTrace();
if(first) {
System.out.println("提示:请使用java21以上版本以提高本软件的数据转发性能!");
first=false;
}
Thread rt=new Thread(r, name);
rt.setDaemon(true);
return rt;
}
}
public static Thread makeVThread(String name, Runnable r) {
try { //return new Thread(r, name);
Class<?> c=Class.forName("java.lang.Thread");
Method m= c.getDeclaredMethod("ofVirtual", null);
Object o=m.invoke(null, null);
Class<?> cb=Class.forName("java.lang.Thread$Builder");
Method mn= cb.getDeclaredMethod("name", String.class);
mn.invoke(o, name);
Method mu= cb.getDeclaredMethod("unstarted", Runnable.class);
return (Thread) mu.invoke(o, r);
//return Thread.ofVirtual().name(name).unstarted(r);
}catch(Throwable e) {
//e.printStackTrace();
if(first) {
System.out.println("提示:请使用java21以上版本以提高本软件的数据转发性能!");
first=false;
}
return new Thread(r, name);
}
}
}
@@ -0,0 +1,28 @@
package org.kne.cloud.network;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.SocketException;
import org.kne.cloud.network.klalb.KLALBVirtualRawSocketImpl;
public class VirtualRawSocket extends RawSocket {
private VirtualRawSocketImpl virtualImpl;
protected VirtualRawSocket(VirtualRawSocketImpl virtualImpl) {
super(virtualImpl);
this.virtualImpl =virtualImpl;
}
public VirtualRawSocket(KLALBVirtualRawSocketImpl virtualImpl, Inet6Address bindAddress) throws SocketException {
super(virtualImpl,bindAddress);
this.virtualImpl =virtualImpl;
}
public VirtualRawSocket(KLALBVirtualRawSocketImpl virtualImpl, Inet6Address bindAddress,
int bindProtocol) throws SocketException {
super(virtualImpl,bindAddress,bindProtocol);
this.virtualImpl =virtualImpl;
}
protected VirtualRawSocketImpl getVirtualImpl() {
return virtualImpl;
}
}
@@ -0,0 +1,13 @@
package org.kne.cloud.network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
public abstract class VirtualRawSocketImpl extends RawSocketImpl {
}
@@ -14,10 +14,16 @@ public interface IPv6NetworkLink {
public boolean isLoopBack();
public Inet6AddressGroup getAddressGroup();
public List<Neighbor> getNeighborsInfo();
public List<RouteItem> getRouteItems();
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException;
public boolean isCongress(IPv6Packet iPv6Packet);
public boolean isCongress(IPv6Packet iPv6Packet,double scale);
public default boolean isCongress(IPv6Packet iPv6Packet) {
return isCongress(iPv6Packet, 1.0);
}
public String getName();
public boolean isUp();
public boolean canSend(IPv6Packet iPv6Packet);
public void setReceiveConsumer(Consumer<IPv6Packet>con);
void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer);
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet);
}
+135 -93
View File
@@ -2,6 +2,7 @@ package org.kne.cloud.network.ipv6;
import java.io.EOFException;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -11,9 +12,12 @@ import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6ExtHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.klalb.KLALBPacket;
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
@@ -24,6 +28,29 @@ import org.kne.cloud.network.srv6.SRv6TLV;
import org.pcap4j.packet.namednumber.IpNumber;
public class IPv6Packet extends NetworkPacket {
private long flowSeqMark=-1;
public long getFlowSeqMark() {
return flowSeqMark;
}
public void setFlowSeqMark(long flowSeqMark) {
this.flowSeqMark = flowSeqMark;
}
private boolean TTLdecreased=false;
public boolean isTTLdecreased() {
return TTLdecreased;
}
public void setTTLdecreased(boolean tTLdecreased) {
TTLdecreased = tTLdecreased;
}
private volatile ByteBuffer IPv6header ;
private volatile List<IPv6ExtHeader> headers = new ArrayList<>();
@@ -41,7 +68,7 @@ public class IPv6Packet extends NetworkPacket {
}
public IPv6Packet() {
IPv6header = NetworkPacket.databufferpool_40.borrow();
IPv6header = NetworkPacket.bufferAllocator.allocate(40);
IPv6header.limit(IPv6_HEADER_LENGTH);
}
@@ -76,6 +103,7 @@ public class IPv6Packet extends NetworkPacket {
public void markCE() {
IPv6header.put(1,(byte) (IPv6header.get(1)|0b00110000));
//new Exception().printStackTrace();
}
public boolean isCE() {
@@ -114,7 +142,24 @@ public class IPv6Packet extends NetworkPacket {
public void setHopLimit(int hopLimit) {
IPv6header.put(7, (byte) hopLimit);
}
public void getRawSourceAddress(byte[] sourceAddress) {
IPv6header.get(8, sourceAddress, 0, sourceAddress.length);
}
public void setRawSourceAddress(byte[] sourceAddress) {
IPv6header.put(8, sourceAddress, 0, sourceAddress.length);
}
public void getRawDestinationAddress(byte[] destinationAddress) {
IPv6header.get(24, destinationAddress, 0,destinationAddress.length);
}
public void setRawDestinationAddress(byte[] destinationAddress) {
IPv6header.put(24, destinationAddress, 0, destinationAddress.length);
}
public Inet6Address getSourceAddress() {
byte[] b = new byte[16];
IPv6header.get(8, b, 0, b.length);
@@ -163,29 +208,6 @@ public class IPv6Packet extends NetworkPacket {
return calcPayloadLength()+IPv6_HEADER_LENGTH;
}
@Override
public void doDisposeAfterSend() {
super.doDisposeAfterSend();
payload.doDisposeAfterSend();
}
@Override
public void dispose() {
super.dispose();
/*ByteBuffer headerx = IPv6header;
IPv6header = null;
if(headerx!=null)
NetworkPacket.databufferpool_40.back(headerx);*/
}
@Override
public void disposeAll() {
super.disposeAll();
for (int i = 0; i < headers.size(); i++) {
headers.get(i).disposeAll();
}
payload.disposeAll();
}
@Override
@@ -241,7 +263,7 @@ public class IPv6Packet extends NetworkPacket {
headers.add(ext);
break;
case 43:
ByteBuffer bbf=NetworkPacket.databufferpool_2048.borrow();
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(2048);
bbf.limit(4);
while (bbf.hasRemaining()) {
if (din.read(bbf) == -1) {
@@ -296,7 +318,11 @@ public class IPv6Packet extends NetworkPacket {
KLALBPacket kp=KLALBPacket.readKLALBPacketFromChannel(din);
this.payload=kp;
break loop;
case 253:
IPv6Payload epld=new IPv6EmptyPayload();
epld.readFromChannel(din, payloadlength);
this.payload=epld;
break loop;
default:
IPv6Payload pld=new IPv6Payload(nextheader);
pld.readFromChannel(din, payloadlength);
@@ -376,35 +402,7 @@ public class IPv6Packet extends NetworkPacket {
//System.out.println(payload);
}*/
@Override
public void lockAll() {
super.lockAll();
for (int i = 0; i < headers.size(); i++) {
headers.get(i).lockAll();
}
payload.lockAll();
}
@Override
public boolean isSomeDisposed() {
if(super.isSomeDisposed()||payload.isSomeDisposed())
return true;
for (Iterator<IPv6ExtHeader> iterator = headers.iterator(); iterator.hasNext();) {
IPv6ExtHeader iPv6ExtHeader = (IPv6ExtHeader) iterator.next();
if(iPv6ExtHeader.isSomeDisposed())
return true;
}
return false;
}
@Override
public void unlockAll() {
payload.unlockAll();
for (int i = 0; i < headers.size(); i++) {
headers.get(i).unlockAll();
}
super.unlockAll();
}
@Override
public String toString() {
@@ -434,7 +432,7 @@ public class IPv6Packet extends NetworkPacket {
this.protocolNumber = protocolNumber;
this.onDefault=isonDefault;
if(onDefault)
this.data=NetworkPacket.databufferpool_65535.borrow();
this.data=NetworkPacket.bufferAllocator.allocate(65535);
}
public int getProtocolNumber() {
@@ -446,13 +444,13 @@ public class IPv6Packet extends NetworkPacket {
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
if(onDefault)
dto.write(data.slice(0,data.limit()));
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
if(onDefault) {
data.limit((int) length);
while (data.hasRemaining()) {
@@ -463,15 +461,7 @@ public class IPv6Packet extends NetworkPacket {
}
}
@Override
public void dispose() {
super.dispose();
/*if(onDefault) {
ByteBuffer datax = data;
data = null;
NetworkPacket.databufferpool_65535.back(datax);
}*/
}
@Override
protected boolean needEndPosition() {
@@ -480,6 +470,28 @@ public class IPv6Packet extends NetworkPacket {
}
public static class IPv6EmptyPayload extends IPv6Payload{
public IPv6EmptyPayload() {
super(253, false);
}
@Override
public long getLength() {
return 0;
}
@Override
public void writeToChannel(WritableByteChannel dto) throws IOException {
}
@Override
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
}
}
public static class IPv6ExtHeader extends NetworkPacket{
private ByteBuffer data ;
@@ -505,9 +517,9 @@ public class IPv6Packet extends NetworkPacket {
this.protocolNumber = protocolNumber;
this.onDefault=isonDefault;
if(onDefault) {
this.data=NetworkPacket.databufferpool_2048.borrow();
this.data=NetworkPacket.bufferAllocator.allocate(2048);
}else {
this.data=NetworkPacket.databufferpool_40.borrow();
this.data=NetworkPacket.bufferAllocator.allocate(8);
}
}
@@ -542,7 +554,7 @@ public class IPv6Packet extends NetworkPacket {
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
if(onDefault) {
int ext=(data.limit()-8)/8;
setExtLength(ext);
@@ -553,7 +565,7 @@ public class IPv6Packet extends NetworkPacket {
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
data.limit(8);
while (data.hasRemaining()) {
if (din.read(data) == -1) {
@@ -576,19 +588,7 @@ public class IPv6Packet extends NetworkPacket {
return false;
}
@Override
public void dispose() {
super.dispose();
/*ByteBuffer bbft=data;
data=null;
if(bbft!=null) {
if(bbft.capacity()==40) {
NetworkPacket.databufferpool_40.back(bbft);
}else {
NetworkPacket.databufferpool_2048.back(bbft);
}
}*/
}
@@ -678,27 +678,37 @@ public class IPv6Packet extends NetworkPacket {
public List<Inet6Address> getAddresses() {
return addresses;
}
public List<IPv6SegmentRoutingTLV> getTlvs() {
return tlvs;
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
setExtLength(calcExtLength()/8);
public void writeToChannel(WritableByteChannel dto) throws IOException {
int exl=calcExtLength();
if(exl%8!=0) {
throw new StreamCorruptedException("extLength % 8 !=0");
}
setExtLength(exl/8);
setLastEntry(addresses.size()-1);
super.writeToChannel(dto);
for (Iterator<Inet6Address> iterator = addresses.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
for(Inet6Address inet6Address:addresses) {
dto.write(ByteBuffer.wrap(inet6Address.getAddress()));
}
for(IPv6SegmentRoutingTLV tlv:tlvs) {
IPv6SegmentRoutingTLV.writeIPv6SegmentRoutingTLVToChannel(dto, tlv);
}
}
private int calcExtLength() {
int tlvsl=0;
for (Iterator<IPv6SegmentRoutingTLV> iterator = tlvs.iterator(); iterator.hasNext();) {
IPv6SegmentRoutingTLV tlve = (IPv6SegmentRoutingTLV) iterator.next();
for(IPv6SegmentRoutingTLV tlve:tlvs) {
tlvsl+=tlve.getLength();
}
return addresses.size()*16+tlvsl;
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
int extl=getExtLength();
int laste=getLastEntry();
@@ -722,6 +732,13 @@ public class IPv6Packet extends NetworkPacket {
//System.out.println("SR:"+addr);
addresses.add(addr);
}
tlvs.clear();
while(usdl<rl) {
IPv6SegmentRoutingTLV tlv=IPv6SegmentRoutingTLV.readIPv6SegmentRoutingTLVFromChannel(din);
usdl+=tlv.getLength();
tlvs.add(tlv);
}
return;
}
@Override
@@ -761,7 +778,20 @@ public class IPv6Packet extends NetworkPacket {
public List<IPv6ExtHeader> getHeaders() {
return headers;
}
public IPv6SegmentRoutingHeader getSRHHeader() {
IPv6SegmentRoutingHeader srhh = null;
List<IPv6ExtHeader> exhs = headers;
for (int j = 0; j < exhs.size(); j++) {
IPv6ExtHeader exh = exhs.get(j);
if (exh instanceof IPv6SegmentRoutingHeader) {
if (((IPv6SegmentRoutingHeader) exh).getRoutingType() == 4) {
srhh = (IPv6SegmentRoutingHeader) exh;
break;
}
}
}
return srhh;
}
/*public IPv6DestinationHeader insertDestinationHeader(int index,int extLength) {
long ptr;
long lth=extLength*8+8;
@@ -831,6 +861,18 @@ public class IPv6Packet extends NetworkPacket {
protected boolean needEndPosition() {
return false;
}
private AtomicInteger rerouteCounter=new AtomicInteger(0);
public AtomicInteger getRerouteCounter() {
return rerouteCounter;
}
private volatile boolean promise=false;
public void setPromise(boolean b) {
promise=b;
}
public boolean isPromise() {
return promise;
}
@@ -3,12 +3,14 @@ package org.kne.cloud.network.ipv6;
import java.io.Closeable;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
@@ -19,14 +21,22 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
import org.kne.cloud.network.srv6.IpV6RoutingSRHData;
import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.PacketReorder;
import org.kne.cloud.network.srv6.SEQSSegmentRoutingTLV;
import org.kne.cloud.network.srv6.SRv6PacketReorder;
import org.kne.cloud.network.srv6.SRv6PacketSeqMarker;
import org.kne.cloud.network.srv6.SRv6StreamSequenceTLV;
import org.kne.cloud.network.srv6.SRv6TLV;
import org.kne.cloud.network.srv6.TCPTransimitAgent;
import org.kne.cloud.network.tun.TUNNetworkDevice;
import org.kne.concurrent.DisruptorExecutor;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.concurrent.SpinLock;
import org.kne.io.KNEChannels;
@@ -42,11 +52,11 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
private Thread tr;
private ThreadPoolExecutor exc = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private Lock slok=new SpinLock();
public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu) throws IOException {
private SRv6PacketSeqMarker seqm=new SRv6PacketSeqMarker();
public IPv6TUNLoopbackNetworkLink(Inet6AddressGroup hostAddress, int mtu,List<InetAddress>dns) throws IOException {
if (tun != null)
throw new IllegalStateException("already open!");
try {
@@ -56,31 +66,42 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
this.hostAddress = hostAddress;
if (hostAddress != null)
tun.setIPAddress(hostAddress.getAddress(), hostAddress.getPrefixLength());
if(dns!=null) {
tun.setDNSAddress(dns);
}
try {
tun.setMTU(mtu);
}catch(IOException e) {
e.printStackTrace();
}
Thread tb = new Thread(() -> {
while (true) {
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
try {
tun.read(tmp);
tmp.flip();
//System.out.println(tmp);
if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) {
while(exc.getQueue().size()>10) {
LockSupport.parkNanos(1000000);
}
exc.execute(() -> {
HighPerformanceExecutor.defaultExecutor.execute(() -> {
try {
IPv6Packet ipp = new IPv6Packet();
ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu);
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
if (con != null) {
monitor.getOutPacketCounterAL().incrementAndGet();
monitor.getOutTrafficAL().addAndGet(ipp.getLength());
ipp.setDisposeAfterSend(true);
ipp.getPayload().setDisposeAfterSend(true);
// ipp.setDisposeAfterSend(true);
// ipp.getPayload().setDisposeAfterSend(true);
ipp.setPromise(true);
if(ipp.getPayload().getProtocolNumber()==6) {
seqm.mark(ipp);
}
con.accept(ipp);
} else {
ipp.dispose();
//ipp.dispose();
}
} catch (IOException e) {
e.printStackTrace();
@@ -88,10 +109,10 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
});
}else {
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
}
} catch (Exception e) {
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
e.printStackTrace();
}
}
@@ -110,9 +131,16 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
e.printStackTrace();
}finally {
slok.unlock();
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
}
} else {
for(SRv6PacketReorder spr:reorder.values()) {
try {
spr.runOrdering();
} catch (IOException e) {
e.printStackTrace();
}
}
LockSupport.parkNanos(1000000L);
}
@@ -132,48 +160,84 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
private SpeedAndTrafficMonitorDataImpl monitor;
private ConcurrentHashMap<FlowSession, SRv6PacketReorder> reorder=new ConcurrentHashMap<>();
@Override
public void sendPacket(IPv6Packet pack, Inet6Address next) throws IOException {
if (tun != null) {/*
* AtomicLong seqs=null; try { IPv6RoutingHeader
* srhh=getRoutingHeaderFromPacket(pack); if(srhh!=null) { byte[]srd=new
* byte[(int) (srhh.getLength()-4)]; srhh.getData().get(4, srd);
* IpV6RoutingSRHData srh=IpV6RoutingSRHData.newInstance( srd,0,srd.length);
* SRv6StreamSequenceTLV ssqv= getStreamSequenceTLV(srh); if(ssqv!=null)
* seqs=new AtomicLong( ssqv.getSequence()); } }catch(IllegalRawDataException
* re) {
*
* }
*/
// System.out.println("add");
while(exc.getQueue().size()>10) {
LockSupport.parkNanos(1000000);
}
exc.execute(()->{
ByteBuffer tmp = NetworkPacket.databufferpool_65535.borrow();
if (tun != null) {
try {
// System.out.println("rev");
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
monitor.getInPacketCounterAL().incrementAndGet();
monitor.getInTrafficAL().addAndGet(pack.getLength());
tmp.flip();
sendQueue.add(tmp);
LockSupport.unpark(tr);
IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
SEQSSegmentRoutingTLV seqs=null;
if(srh!=null) {
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
for (int i = 0; i < l.size(); i++) {
IPv6SegmentRoutingTLV tlv=l.get(i);
if(tlv instanceof SEQSSegmentRoutingTLV) {
seqs=(SEQSSegmentRoutingTLV) tlv;
break;
}
}
}
sendPacket0(pack,seqs);
} catch (IOException e) {
NetworkPacket.databufferpool_65535.back(tmp);
//NetworkPacket.databufferpool_65535.back(tmp);
e.printStackTrace();
}
pack.disposeAll();
});
//pack.disposeAll();
} else {
pack.disposeAll();
//pack.disposeAll();
}
}
private void sendPacket0(IPv6Packet pack,SEQSSegmentRoutingTLV seqs) throws IOException {
if(seqs!=null&&seqs.isKeepOrder()) {
FlowSession fss=pack.getFlowSession();
SRv6PacketReorder newr= new SRv6PacketReorder(new PacketConsumer() {
@Override
public void accept(IPv6Packet packx) throws IOException {
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
packx.writeToChannel(KNEChannels.newWritableChannel(tmp));
monitor.getInPacketCounterAL().incrementAndGet();
monitor.getInTrafficAL().addAndGet(packx.getLength());
tmp.flip();
sendQueue.add(tmp);
LockSupport.unpark(tr);
}
});
SRv6PacketReorder olr=reorder.putIfAbsent(fss,newr);
if(olr==null) {
olr=newr;
}
olr.put(pack,seqs.getSequence());
}else {
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
monitor.getInPacketCounterAL().incrementAndGet();
monitor.getInTrafficAL().addAndGet(pack.getLength());
tmp.flip();
sendQueue.add(tmp);
LockSupport.unpark(tr);
}
}
private SRv6StreamSequenceTLV getStreamSequenceTLV(IpV6RoutingSRHData srh) {
List<SRv6TLV> stv = srh.getTlvs();
for (Iterator iterator = stv.iterator(); iterator.hasNext();) {
@@ -199,8 +263,8 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
}
@Override
public boolean isCongress(IPv6Packet iPv6Packet) {
return sendQueue.size() > 1000;
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
return sendQueue.size() > 1000*scale;
}
@Override
@@ -243,6 +307,36 @@ public class IPv6TUNLoopbackNetworkLink implements IPv6NetworkLink, Closeable, A
return hostAddress;
}
@Override
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
}
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist=new ArrayList<>();
rlist.add(new RouteItem(new Inet6AddressGroup(this.getAddressGroup().getAddress(), 128),
this.getAddressGroup().getAddress(), this, "Direct", 0, 1, null, "D",true));
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
rlist.add(ris);
}
return rlist;
}
@Override
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
return false;
}
}
@@ -63,13 +63,43 @@ public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
public int getPrefixLength() {
return prefixLength;
}
private byte[] cachedRawAddress;
public byte[] getRawAddress() {
if(cachedRawAddress==null) {
return (cachedRawAddress=address.getAddress());
}else {
return cachedRawAddress;
}
}
private byte[] cachedAndm;
private byte[] getAndm(byte[]mask) {
if(cachedAndm==null) {
return (cachedAndm=and0(mask ,getRawAddress()));
}else {
return cachedAndm;
}
}
public boolean checkMatch(Inet6Address ia) {
byte[]mask=maskTransf[prefixLength];
byte[]andj=and0(mask,ia.getAddress());
byte[]andm=and0(mask ,address.getAddress());
return Arrays.equals(andj,andm);
byte[]andm=getAndm(mask);
return andeq0(mask,ia.getAddress(),andm);
}
private byte[] and0(byte[] bs, byte[] address2) {
public boolean checkMatch(byte[] ia) {
byte[]mask=maskTransf[prefixLength];
byte[]andm=getAndm(mask);
return andeq0(mask,ia,andm);
}
private static boolean andeq0(byte[] bs, byte[] address2, byte[] andm) {
for (int i = 0; i < bs.length; i++) {
if(andm[i]!=(byte) (bs[i]&address2[i])) {
return false;
}
}
return true;
}
private static byte[] and0(byte[] bs, byte[] address2) {
byte[]rez=new byte[bs.length];
for (int i = 0; i < rez.length; i++) {
rez[i]=(byte) (bs[i]&address2[i]);
@@ -90,4 +120,5 @@ public class Inet6AddressGroup implements Comparable<Inet6AddressGroup>{
address=(Inet6Address) Inet6Address.getByAddress(b);
prefixLength=in.read();
}
}
@@ -5,11 +5,14 @@ import java.net.InetAddress;
import java.util.Objects;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
import org.kne.cloud.network.te.BandwidthDistributer;
public class Neighbor {
private Inet6AddressGroup address;
private Inet6AddressGroup locator;
private MonitorData monitor;
private BandwidthDistributer<Inet6Address> bandwidthDistributer;
public MonitorData getMonitor() {
return monitor;
}
@@ -19,12 +22,21 @@ public class Neighbor {
public Inet6AddressGroup getLocator() {
return locator;
}
public BandwidthDistributer<Inet6Address> getBandwidthDistributer() {
return bandwidthDistributer;
}
public Neighbor(Inet6AddressGroup address, Inet6AddressGroup locator, MonitorData monitor) {
super();
this.address = address;
this.locator = locator;
this.monitor = monitor;
}
public Neighbor(Inet6AddressGroup peerAddress, Inet6AddressGroup remoteVaddr, QueueingMonitorDataImpl monitor2,
BandwidthDistributer<Inet6Address> bandwidthDistributer) {
this(peerAddress,remoteVaddr,monitor2);
this.bandwidthDistributer=bandwidthDistributer;
}
@Override
public String toString() {
return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]";
+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.QueueingMonitorDataImpl;
public class RouteItem implements Comparable<RouteItem>{
public class RouteItem implements Comparable<RouteItem>,Cloneable{
private Inet6AddressGroup destination;
private Inet6Address nexthop;
private IPv6NetworkLink destlink;
@@ -20,6 +20,7 @@ public class RouteItem implements Comparable<RouteItem>{
private long cost;
private String flag;
private MonitorData monitor;
private boolean isLoopback;
public String getFlag() {
return flag;
}
@@ -44,7 +45,7 @@ public class RouteItem implements Comparable<RouteItem>{
&& pre == other.pre && Objects.equals(proto, other.proto);
}
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
long cost,String flag) {
long cost,String flag,boolean isLoopback) {
super();
this.destination = destination;
this.nexthop = nexthop;
@@ -53,9 +54,10 @@ public class RouteItem implements Comparable<RouteItem>{
this.pre = pre;
this.cost = cost;
this.flag=flag;
this.isLoopback=isLoopback;
}
public RouteItem(Inet6AddressGroup destination, Inet6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
long cost,MonitorData monitor,String flag) {
long cost,MonitorData monitor,String flag,boolean isLoopback) {
super();
this.destination = destination;
this.nexthop = nexthop;
@@ -65,6 +67,7 @@ public class RouteItem implements Comparable<RouteItem>{
this.cost = cost;
this.monitor=monitor;
this.flag=flag;
this.isLoopback=isLoopback;
}
public Inet6AddressGroup getDestination() {
return destination;
@@ -81,6 +84,9 @@ public class RouteItem implements Comparable<RouteItem>{
public int getPre() {
return pre;
}
public boolean isLoopback() {
return isLoopback;
}
@Override
public String toString() {
return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop().getHostAddress()+"\t"+getDestlink().getName();
@@ -91,6 +97,9 @@ public class RouteItem implements Comparable<RouteItem>{
public boolean checkMatch(Inet6Address ia) {
return destination.checkMatch(ia);
}
public boolean checkMatch(byte[] ia) {
return destination.checkMatch(ia);
}
@Override
public int compareTo(RouteItem o) {
int v1=destination.compareTo(o.destination);
@@ -105,7 +114,35 @@ public class RouteItem implements Comparable<RouteItem>{
if(monitor==null||o.monitor==null||(!(monitor instanceof DelayMonitorData))||(!(o.monitor instanceof DelayMonitorData)))
return v3;
if(!(monitor instanceof QueueingMonitorDataImpl)||!(o.monitor instanceof QueueingMonitorDataImpl))
return Long.compare(((DelayMonitorData)monitor).getOutDelay(), ((DelayMonitorData)o.monitor).getOutDelay());
return Long.compare(((DelayMonitorData)monitor).getOutDelay()+((QueueingMonitorDataImpl)monitor).getQueueingDelay(), ((DelayMonitorData)o.monitor).getOutDelay()+((QueueingMonitorDataImpl)o.monitor).getQueueingDelay());
return Long.compare(outDelay, o.outDelay);
return Long.compare(outDelay+queueingDelay, o.outDelay+o.queueingDelay);
}
@Override
public Object clone() {
try {
RouteItem ri=(RouteItem) super.clone();
if(monitor!=null)
ri.monitor=(MonitorData) monitor.clone();
return ri;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
long outDelay;
long queueingDelay;
public void preSort() {
if(monitor!=null) {
outDelay=((DelayMonitorData)monitor).getOutDelay();
if(monitor instanceof QueueingMonitorDataImpl) {
queueingDelay=((QueueingMonitorDataImpl)monitor).getQueueingDelay();
}
}
}
public boolean ECMPequals(RouteItem prevr) {
return prevr.getDestination().getPrefixLength()==getDestination().getPrefixLength()&&prevr.getPre()==getPre()&&prevr.getCost()==getCost();
}
}
+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 {
private static final int HEADER_LENGTH=28;
private static final int HEADER_LENGTH=35;
public ACKTPacket(int sport,int dport,long number,boolean avaliable,boolean congress,long rcvSpeed,int sendcount) {
public ACKTPacket(int sport,int dport,long number,long avaliableRcvWindow,boolean congress,long rcvSpeed,int sendcount) {
super(ACKT,HEADER_LENGTH);
klalbHeader.putInt(sport);
klalbHeader.putInt(dport);
klalbHeader.putLong(number);
klalbHeader.put((byte) sendcount);
klalbHeader.put((byte) (avaliable?1:0));
klalbHeader.putLong(avaliableRcvWindow);
klalbHeader.put((byte) (congress?1:0));
klalbHeader.putLong(rcvSpeed);
}
@@ -33,7 +33,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
@Override
public String toString() {
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] "+isAvaliable();
return "ACKT "+getSport()+"->"+getDport()+" "+getNumber()+"[] avaliable:"+getAvaliableRcvWindow();
}
public int getSport() {
@@ -41,7 +41,7 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
}
public boolean isCongress() {
return klalbHeader.get(19)!=0;
return klalbHeader.get(26)!=0;
}
public int getDport() {
@@ -52,8 +52,8 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
return klalbHeader.getLong(9);
}
public boolean isAvaliable() {
return klalbHeader.get(18)!=0;
public long getAvaliableRcvWindow() {
return klalbHeader.getLong(18);
}
@@ -61,6 +61,6 @@ public class ACKTPacket extends KLALBPacket implements PortPacket {
return klalbHeader.getInt(17);
}
public long getRcvSpeed() {
return klalbHeader.getLong(20);
return klalbHeader.getLong(27);
}
}
@@ -41,7 +41,7 @@ public class ADDLINESPacket extends KLALBPacket {
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
byte[]bta=lines.getBytes(Charset.forName("UTF-8"));
klalbHeader.putChar(1,(char) bta.length);
super.writeToChannel(dto);
@@ -49,7 +49,7 @@ public class ADDLINESPacket extends KLALBPacket {
}
@Override
protected void readFromChannel(ReadableByteChannel din) throws IOException {
public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din);
int lth=klalbHeader.getChar(1);
byte[]b=new byte[lth];
@@ -0,0 +1,97 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.NetworkPacket;
import org.kne.io.KNEChannels;
public abstract class AbstractKLALBPacketLink implements KLALBPacketLink {
private AtomicLong[] inputTrafficCounters;
private AtomicLong[] outputTrafficCounters;
private AtomicLong[] inputPacketsCounters;
private AtomicLong[] outputPacketsCounters;
@Override
public void setOutputPacketsCounters(AtomicLong[] outCounter) {
outputPacketsCounters=outCounter;
}
@Override
public void setInputPacketsCounters(AtomicLong[] inCounter) {
inputPacketsCounters=inCounter;
}
@Override
public void setOutputTrafficCounters(AtomicLong[] outCounter) {
this.outputTrafficCounters=outCounter;
}
@Override
public void setInputTrafficCounters(AtomicLong[] inCounter) {
this.inputTrafficCounters=inCounter;
}
public AtomicLong[] getInputTrafficCounters() {
return inputTrafficCounters;
}
public AtomicLong[] getOutputTrafficCounters() {
return outputTrafficCounters;
}
public AtomicLong[] getInputPacketsCounters() {
return inputPacketsCounters;
}
public AtomicLong[] getOutputPacketsCounters() {
return outputPacketsCounters;
}
protected void incOutput(int packetLength) {
if(outputTrafficCounters!=null) {
for(AtomicLong al:outputTrafficCounters) {
al.addAndGet(packetLength);
}
}
if(outputPacketsCounters!=null) {
for(AtomicLong al:outputPacketsCounters) {
al.incrementAndGet();
}
}
}
protected void incInput(int packetLength) {
if(inputTrafficCounters!=null) {
for(AtomicLong al:inputTrafficCounters) {
al.addAndGet(packetLength);
}
}
if(inputPacketsCounters!=null) {
for(AtomicLong al:inputPacketsCounters) {
al.incrementAndGet();
}
}
}
@Override
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
ByteBuffer dataWrite=NetworkPacket.bufferAllocator.allocate((int) kp.getLength());
//dataWrite.clear();
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel( dataWrite), kp);
dataWrite.flip();
writePacket(dataWrite);
}
@Override
public KLALBPacket readKLALBPacket() throws IOException {
ByteBuffer buffer=readPacket();
if(buffer==null) {
return null;
}
return KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(buffer));
}
}
@@ -1,113 +0,0 @@
package org.kne.cloud.network.klalb;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.concurrent.SpinLock;
import org.kne.debug.TimeDebugger;
/*
public class ByteBufferPool {
private Queue<ByteBuffer> rec;
private int maxcount;
private int length;
private boolean direct;
public ByteBufferPool(int maxcount, int length,boolean direct) {
super();
this.maxcount = maxcount;
this.length = length;
this.direct=direct;
rec=new ConcurrentLinkedQueue<ByteBuffer>();
}
public ByteBufferPool(int maxcount, int length) {
this(maxcount, length, true);
}
public void back(ByteBuffer b) {
if(b.capacity()!=length)
throw new IllegalArgumentException("wrong length");
b.clear();
rec.offer(b);
}
public ByteBuffer borrow() {
ByteBuffer b=rec.poll();
if(b==null) {
if(direct)
b=ByteBuffer.allocateDirect(length);
else
b=ByteBuffer.allocate(length);
}
return b;
}
public int getMaxCount() {
return maxcount;
}
public int getLength() {
return length;
}
}*/
public class ByteBufferPool {
private ByteBuffer[]rec;
private volatile int pos=0;
private Lock lock=new SpinLock();
private int maxcount;
private int length;
private int mcj;
private boolean direct;
public ByteBufferPool(int maxcount, int length,boolean direct) {
super();
this.maxcount = maxcount;
this.length = length;
this.direct=direct;
rec=new ByteBuffer[maxcount];
mcj=rec.length-1;
}
public ByteBufferPool(int maxcount, int length) {
this(maxcount, length, true);
}
public void back(ByteBuffer b) {
if(b.capacity()!=length)
throw new IllegalArgumentException("wrong length");
b.clear();
lock.lock();
try {
if(pos<mcj)
rec[++pos]= b;
}finally{
lock.unlock();
}
}
public ByteBuffer borrow() {
ByteBuffer b=null;
lock.lock();
try {
if(pos>0) {
b=rec[pos--];
//rec[pos--]=null;
}
}finally{
lock.unlock();
}
if(b==null) {
if(direct)
b=ByteBuffer.allocateDirect(length);
else
b=ByteBuffer.allocate(length);
}
return b;
}
public int getMaxCount() {
return maxcount;
}
public int getLength() {
return length;
}
}
+6 -2
View File
@@ -2,7 +2,11 @@ package org.kne.cloud.network.klalb;
public class CONST {
public static final String klalb="KLALB";
public static final String klalbver="3.0";
public static final String klalbver="3.2";
public static final int bversion=3;
public static final int sversion=0;
public static final int sversion=1;
public static final int itemwidth = 720;
public static final int linepanelheight = 45;
public static final int settingheight = 30;
}
@@ -39,7 +39,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
klalbHeader.putChar((char) 0);
//dataBuffer.limit(mtulimit);
dataBuffer=ByteBuffer.allocate(mtulimit);
dataBuffer=NetworkPacket.bufferAllocator.allocate(mtulimit);
}
public int getSendcount() {
@@ -100,7 +100,7 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.put(17, (byte) getSendCounter());
klalbHeader.putChar(18, (char) dataBuffer.limit());
super.writeToChannel(dto);
@@ -109,13 +109,13 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
}
@Override
protected void readFromChannel(ReadableByteChannel din) throws IOException {
public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din);
numberc=Long.MIN_VALUE;
int limit=klalbHeader.getChar(18);
//dataBuffer.clear();
//dataBuffer.limit();
dataBuffer=ByteBuffer.allocate(limit);
dataBuffer=NetworkPacket.bufferAllocator.allocate(limit);
while(dataBuffer.hasRemaining()){
if(din.read(dataBuffer)==-1) {
throw new EOFException();
@@ -124,12 +124,5 @@ public class DATATPacket extends KLALBPacket implements PortPacket{
dataBuffer.flip();
}
@Override
public void dispose() {
super.dispose();
/*ByteBuffer datan=dataBuffer;
dataBuffer=null;
NetworkPacket.databufferpool_65535.back(datan);*/
}
}
@@ -125,12 +125,14 @@ import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import org.kne.cloud.network.DatagramServerSocket;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.SpeedLimiter;
public class DatagramKLALBPacketLink implements KLALBPacketLink {
public class DatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
@Override
public String toString() {
@@ -145,17 +147,20 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
private ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
private DataOutputStream dos=new DataOutputStream(bos);
@Override
public void writePacket(KLALBPacket kp) throws IOException {
/*@Override
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
//System.out.println(" TX:"+kp);
KLALBPacket.writeKLALBPacketToStream(dos, kp);
byte[]bt=bos.toByteArray();
DatagramPacket dp=new DatagramPacket(bt,bt.length);
ds.send(dp);
bos.reset();
}
private byte[]bc=new byte[65535];
DataInputStream dis;
@Override
public KLALBPacket readPacket() throws IOException {
public KLALBPacket readKLALBPacket() throws IOException {
KLALBPacket kp=null;
do {
if(dis==null) {
@@ -176,8 +181,37 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
//System.out.println(" RX:"+kp);
}while(true);
return kp;
}*/
byte[]b=new byte[65536];
@Override
public void writePacket(ByteBuffer kp) throws IOException {
int length=kp.remaining();
incOutput(length);
kp.get(b,0,length);
DatagramPacket dp=new DatagramPacket(b,length);
ds.send(dp);
}
byte[]c=new byte[65536];
@Override
public ByteBuffer readPacket() throws IOException {
DatagramPacket dp;
if(ds instanceof DatagramServerSocket.SubDatagramSocket) {
dp=((DatagramServerSocket.SubDatagramSocket) ds).receive();
}else {
dp=new DatagramPacket(c, c.length);
ds.receive(dp);
}
incInput(dp.getLength());
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(dp.getLength());
bbf.put(dp.getData(),0,dp.getLength());
bbf.flip();
return bbf;
}
@Override
public void close() throws IOException {
ds.close();
@@ -200,10 +234,7 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
@Override
public void flush() throws IOException {
byte[]bt=bos.toByteArray();
DatagramPacket dp=new DatagramPacket(bt,bt.length);
ds.send(dp);
bos.reset();
}
@@ -211,4 +242,6 @@ public class DatagramKLALBPacketLink implements KLALBPacketLink {
public boolean isStream() {
return false;
}
}
@@ -0,0 +1,47 @@
package org.kne.cloud.network.klalb;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.Objects;
import java.util.UUID;
public class IPSequence {
private UUID uuid;
private boolean isPromise;
public IPSequence(UUID uuid, boolean isPromise) {
super();
this.uuid = uuid;
this.isPromise = isPromise;
}
public UUID getUuid() {
return uuid;
}
public boolean isPromise() {
return isPromise;
}
@Override
public String toString() {
return "IPSequence [uuid=" + uuid + ", isPromise=" + isPromise + "]";
}
@Override
public int hashCode() {
return Objects.hash(uuid);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IPSequence other = (IPSequence) obj;
return Objects.equals(uuid, other.uuid);
}
}
@@ -10,26 +10,6 @@ import org.kne.cloud.network.ipv6.IPv6Packet;
public class IPv6OverKLALBPacket extends KLALBPacket {
private static final int HEADER_LENGTH=9;
@Override
public boolean isSomeDisposed() {
return super.isDisposed()||ipv6Packet.isSomeDisposed();
}
@Override
public void lockAll() {
super.lockAll();
ipv6Packet.lockAll();
}
@Override
public void unlockAll() {
ipv6Packet.unlockAll();
super.unlockAll();
}
@Override
@@ -56,12 +36,6 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
super(bb,HEADER_LENGTH);
this.ipv6Packet=new IPv6Packet();
}
@Override
public void disposeAll() {
super.disposeAll();
ipv6Packet.disposeAll();
}
public IPv6Packet getIPv6Packet() {
return ipv6Packet;
@@ -78,24 +52,16 @@ public class IPv6OverKLALBPacket extends KLALBPacket {
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.putLong(1, ipv6Packet.getLength());
super.writeToChannel(dto);
ipv6Packet.writeToChannel(dto);
}
@Override
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
super.readFromChannel(din,length);
ipv6Packet.readFromChannel(din, klalbHeader.getLong(1));
}
@Override
public void doDisposeAfterSend() {
super.doDisposeAfterSend();
ipv6Packet.doDisposeAfterSend();
}
}
@@ -56,14 +56,18 @@ import org.kne.cloud.network.ipv6.IPv6TUNLoopbackNetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.cloud.network.te.BandwidthDistributer;
import org.kne.cloud.network.te.DWRRLoadingBalanceAlgorithm;
import org.kne.concurrent.DisruptorExecutor;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
import org.pcap4j.packet.IpV6Packet.IpV6Header;
import com.google.gson.JsonElement;
public class KLALBController {
@@ -80,6 +84,12 @@ public class KLALBController {
private static List<IPMulticastDiscovery> ipmd=new ArrayList<>();
private List<InetAddress>dnsAddresses=new ArrayList<>();
public List<InetAddress> getDnsAddresses() {
return dnsAddresses;
}
private Timer twk=new Timer("网卡检测扫描计时器", true);
{
@@ -210,48 +220,49 @@ public class KLALBController {
continue;
}
if(networkInterface.isUp()) {
boolean b=true;
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
loop:while (ei.hasMoreElements()) {
InetAddress bidr = (InetAddress) ei.nextElement();
for (Iterator<IPMulticastDiscovery> iterator = ipmd.iterator(); iterator.hasNext();) {
IPMulticastDiscovery ipMulticastDiscovery = (IPMulticastDiscovery) iterator.next();
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())) {
b=false;
break;
if(networkInterface.equals(ipMulticastDiscovery.getNinterface())&&bidr.equals(ipMulticastDiscovery.getBind().getAddress())) {
continue loop;
}
}
if(b) {
/*InetAddress bidr=null;
Enumeration<InetAddress>ei= networkInterface.getInetAddresses();
while (ei.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) ei.nextElement();
if(inetAddress instanceof Inet6Address) {
Inet6Address i6=(Inet6Address) inetAddress;
if(i6.getHostAddress().startsWith("fe80")) {
bidr=i6;
break;
}
}
}
if(bidr!=null)*/
try {
InetAddress bidr=InetAddress.getByName("::0");
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable);
//InetAddress bidr=InetAddress.getByName("::0");
if(bidr instanceof Inet6Address) {
IPMulticastDiscovery ipd=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("ff02::2486"),DISCOVERY_PORT), networkInterface,selflineTable,10000L);
ipd.setCon((mpa)->{
//System.out.println("添加本地IPv6链路:"+mpa);
addRemoteLines(mpa);
try {
if(!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
});
ipd.start();
ipmd.add(ipd);
bidr=InetAddress.getByName("0.0.0.0");
IPMulticastDiscovery ipd2=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("224.0.0.86"),DISCOVERY_PORT), networkInterface,selflineTable);
}else if(bidr instanceof Inet4Address) {
//bidr=InetAddress.getByName("0.0.0.0");
IPMulticastDiscovery ipd2=new IPMulticastDiscovery(new InetSocketAddress(bidr,DISCOVERY_PORT), new InetSocketAddress(InetAddress.getByName("224.0.0.86"),DISCOVERY_PORT), networkInterface,selflineTable,10000L);
ipd2.setCon((mpa)->{
//System.out.println("添加本地IPv4链路:"+mpa);
addRemoteLines(mpa);
try {
if(!checkIsSelf(mpa))
addRemoteLines(mpa);
} catch (UnknownHostException e) {
}
});
ipd2.start();
ipmd.add(ipd2);
}
System.out.println("添加网卡:"+networkInterface);
}catch(BindException e) {
//e.printStackTrace();
@@ -259,8 +270,11 @@ public class KLALBController {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//}
}
}
@@ -270,6 +284,11 @@ public class KLALBController {
}
}
private boolean checkIsSelf(MultipurposeSocketAddress inetAddress) throws UnknownHostException {
return inetAddress.getInetAddress().isAnyLocalAddress()||inetAddress.getInetAddress().isLoopbackAddress()||selflineTable.contains(inetAddress);
}
}, 2000, 2000);
}
public SpeedAndTrafficMonitorDataImpl getLinkMonitor() {
@@ -326,10 +345,10 @@ public class KLALBController {
}
private Inet6AddressGroup self;
//private Inet6AddressGroup self;
public Inet6Address getSelf() {
return self.getAddress();
public Inet6AddressGroup getSelf() {
return srv6Router.getLocator();
}
private List<KLALBRemoteLine> lines=new CopyOnWriteArrayList<>();
private ReadWriteLock lineslock=new ReentrantReadWriteLock();
@@ -339,11 +358,16 @@ public class KLALBController {
}
private PortBinder streamPortBinder=new PortBinder(this);
private PortBinder rawPortBinder=new PortBinder(this);
protected PortBinder getStreamPortBinder() {
return streamPortBinder;
}
public PortBinder getRawPortBinder() {
return rawPortBinder;
}
public void reconnectImmediately() {
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
@@ -380,7 +404,8 @@ public class KLALBController {
}
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {
public List<KLALBRemoteLine> addRemoteLines(MultipurposeSocketAddress target) {lineslock.writeLock().lock();
try {
List<KLALBRemoteLine>added=new ArrayList<>();
try {
Enumeration<NetworkInterface>eu= NetworkInterface.getNetworkInterfaces();
@@ -419,6 +444,9 @@ public class KLALBController {
}
return added;
}finally {
lineslock.writeLock().unlock();
}
}
public List<KLALBRemoteLine> removeRemoteLines(MultipurposeSocketAddress mpsa) {
@@ -477,15 +505,15 @@ public class KLALBController {
}
public void addRemoteLine(KLALBRemoteLine krs) {
lineslock.writeLock().lock();
try {
krs.setPacketReceiver(prc);
krs.setKlalbController(this);
krs.setLocalVaddrSupplier(()->{return self;});
krs.setLocalVaddrSupplier(()->{return getSelf();});
krs.startIO();
String selflineTable=generateSelfLineTable();
if(selflineTable!=null&&!selflineTable.equals(""))
krs.sendPacket(new ADDLINESPacket(selflineTable));
lineslock.writeLock().lock();
try {
lines.add(krs);
}finally {
lineslock.writeLock().unlock();
@@ -502,16 +530,12 @@ public class KLALBController {
}
return sbd.toString();
}
public KLALBController(Inet6Address self) {
this.self =new Inet6AddressGroup(self, PREFIX);
loadSRv6ProtocolStack();
}
private class KLALBProtocolPacketConsumer implements PacketConsumer{
@Override
public void accept(IPv6Packet packx) throws IOException {
HighPerformanceExecutor.defaultExecutor.execute(()->{
//HighPerformanceExecutor.defaultExecutor.execute(()->{
/*System.out.println("RCV:"+packx.getPayload().getData());
byte[]b=new byte[packx.getPayload().getData().limit()];
@@ -539,18 +563,18 @@ public class KLALBController {
}
}
}
packx.dispose();
});
//packx.dispose();
//});
}
}
private void loadSRv6ProtocolStack() {
srv6Router=new SRv6Router(self);
private void loadSRv6ProtocolStack(Inet6AddressGroup selfx,boolean enableVirtualAdapter) {
srv6Router=new SRv6Router(selfx);
if(enableVirtualAdapter)
try {
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU);
IPv6TUNLoopbackNetworkLink tunlink=new IPv6TUNLoopbackNetworkLink(new Inet6AddressGroup( srv6Router.getLocator().getAddress(),32),SRv6Router.MTU, dnsAddresses);
tunlink.setMonitor(datatMonitor);
srv6Router.getLinkTabel().add(tunlink);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
@@ -558,8 +582,19 @@ public class KLALBController {
srv6Router.getProtocolNumberRegister().put(KLALBPacket.KLALB_PROTOCOL_NUMBER,new KLALBProtocolPacketConsumer());
System.out.println("SRv6协议栈已加载");
}
public KLALBController() {
this(true,null);
}
public KLALBController (Inet6Address self) {
this(self,true,null);
}
public KLALBController(Inet6Address self,boolean enableVirtualAdapter,List<InetAddress> dnsaddr) {
this.dnsAddresses=dnsaddr;
Inet6AddressGroup selfg =new Inet6AddressGroup(self, PREFIX);
loadSRv6ProtocolStack(selfg,enableVirtualAdapter);
}
public KLALBController(boolean enableVirtualAdapter,List<InetAddress> dnsaddr) {
this.dnsAddresses=dnsaddr;
SecureRandom sc=new SecureRandom();
byte[]v=new byte[16];
sc.nextBytes(v);
@@ -569,27 +604,31 @@ public class KLALBController {
v[3]=1;
v[14]=0;
v[15]=1;
Inet6AddressGroup selfx=null;
try {
this.self=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
selfx=new Inet6AddressGroup( (Inet6Address) InetAddress.getByAddress(v),PREFIX);
} catch (UnknownHostException e) {
e.printStackTrace();
}
loadSRv6ProtocolStack();
loadSRv6ProtocolStack(selfx,enableVirtualAdapter);
}
public KLALBController(List<InetAddress> daddr) {
this(true,daddr);
}
public KLALBController(Inet6Address self, List<InetAddress> daddr) {
this(self,true,daddr);
}
public KLALBController(boolean enableVirtualAdapter) {
this(enableVirtualAdapter,null);
}
protected KLALBVirtualSocketImpl createVirtualImpl() {
return new KLALBVirtualSocketImpl(this);
}
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet)
throws IOException {
sendPacketToLinkAddress(addr, packet, 1);
}
private SRv6Router srv6Router;
@@ -603,7 +642,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
@Override
public void run() {
Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
//Map<Inet6Address,DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 =new ConcurrentHashMap<>();
for (Iterator<KLALBRemoteLine> iterator = lines.iterator(); iterator.hasNext();) {
KLALBRemoteLine klalbRemoteLine = (KLALBRemoteLine) iterator.next();
if(klalbRemoteLine.isClosed()) {
@@ -615,20 +654,20 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
}
}else {
if(klalbRemoteLine.getRemoteVaddr()!=null&&klalbRemoteLine.getMonitor().getState()==MonitorData.ONLINE) {
if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
/* if(lines2.containsKey(klalbRemoteLine.getRemoteVaddr())) {
lines2.get(klalbRemoteLine.getRemoteVaddr()).getEntries().add(klalbRemoteLine);
}else {
ArrayList<KLALBRemoteLine>al1=new ArrayList<>();
al1.add(klalbRemoteLine);
lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1));
}
}*/
if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) {
srv6Router.getLinkTabel().add(klalbRemoteLine);
}
}
}
}
for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
/*for (Iterator<Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> klalbRemoteLine = (Entry<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>>) iterator.next();
List<KLALBRemoteLine> lineList=klalbRemoteLine.getValue().getEntries();
lineList.forEach((r)->{
@@ -641,7 +680,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
}
}
KLALBController.this.lines2=lines2;
KLALBController.this.lines2=lines2;*/
if(srv6Router!=null) {
srv6Router.getLinkTabel().removeIf((v)->{
return (v instanceof KLALBRemoteLine)&&(!v.isUp());
@@ -649,7 +688,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
srv6Router.updateRouteTabel();
}
}
}, 1, 1);
}, 2, 2);
}
/*private void updateLines2(Inet6Address addr) throws SocketTimeoutException {
List<KLALBRemoteLine> l=new ArrayList();
@@ -675,122 +714,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
lines2.put(addr, l);
}
}*/
private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
protected void sendPacketToLinkAddress(Inet6Address addr, KLALBPacket packet, int count)
throws IOException {
if(packet==null)
throw new NullPointerException("packet is null!");
//TimeDebugger tdb=new TimeDebugger();
//tdb.putTime("start");
packet.genseq();
/*loop:while(true) {
if(packet.isDisposed())
return;
List<KLALBRemoteLine> lines2x;
lines2x=lines2.get(addr);
if (lines2x == null || lines2x.isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
int count0 = Math.min(count, lines2x.size());
for (int i = 0; i < lines2x.size(); i++) {
KLALBRemoteLine krst =lines2x.get(i);
if(krst.getMonitor().getState()==MonitorData.ONLINE)
if(!packet.getSendRecord().contains(krst)) {
if(krst.getQueue().size()<10) {
packet.getSendRecord().add(krst);
//System.out.println(krst);
krst.sendPacket(packet);
count0--;
if (count0 <= 0)
break loop;
}
}
}
for (int i = 0; i < lines2x.size(); i++) {
KLALBRemoteLine krst =lines2x.get(i);
if(krst.getMonitor().getState()==MonitorData.ONLINE)
if(packet.getSendRecord().contains(krst)) {
if(krst.getQueue().size()<10) {
packet.getSendRecord().add(krst);
//System.out.println(krst);
krst.sendPacket(packet);
count0--;
if (count0 <= 0)
break loop;
}
}
}
LockSupport.parkNanos(50000);
//tdb.putTime("sendfailed");
}*/
//tdb.putTime("sendsuccess");
//tdb.print();
/* List<KLALBRemoteLine> lines2x;
lines2x=lines2.get(addr);
if (lines2x == null || lines2x.isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
KLALBRemoteLine kr= lines2x.get(0);
kr.sendPacket(packet);
packet.getSendRecord().add(kr);*/
/*loop:while(true) {
if(packet.isDisposed())
return;
DWRRLoadingBalanceAlgorithm<KLALBRemoteLine> dwrlines2x;
dwrlines2x=lines2.get(addr);
if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) {
throw new NoRouteToHostException("address unreachable: " + addr);
}
List<KLALBRemoteLine>lines2x=dwrlines2x.roundEntriesList();
int count0 = Math.min(count, lines2x.size());
for (int i = 0; i < lines2x.size(); i++) {
KLALBRemoteLine krst =lines2x.get(i);
if(krst.getMonitor().getState()==MonitorData.ONLINE)
if(!packet.getSendRecord().contains(krst)) {
if(krst.getQueue().size()<5) {
packet.getSendRecord().add(krst);
//System.out.println(krst);
krst.sendPacket(packet);
count0--;
if (count0 <= 0)
break loop;
}
}
}
for (int i = 0; i < lines2x.size(); i++) {
KLALBRemoteLine krst =lines2x.get(i);
if(krst.getMonitor().getState()==MonitorData.ONLINE)
if(packet.getSendRecord().contains(krst)) {
if(krst.getQueue().size()<5) {
packet.getSendRecord().add(krst);
//System.out.println(krst);
krst.sendPacket(packet);
count0--;
if (count0 <= 0)
break loop;
}
}
}
LockSupport.parkNanos(50000);
//tdb.putTime("sendfailed");
}*/
}
//private Map<Inet6Address, DWRRLoadingBalanceAlgorithm<KLALBRemoteLine>> lines2 = new ConcurrentHashMap<>();
@@ -804,11 +728,8 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
HighPerformanceExecutor.defaultExecutor.execute(()->{
IPv6Packet ipv=new IPv6Packet();
packet.getDisposeLock().lock();
try {
if(packet.isDisposed()) {
return;
}
if(showpacket)
System.out.println("KLALB_TX:"+packet);
@@ -816,10 +737,15 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
ipv.setTrafficClass(0);
ipv.setFlowLabel(flowlabel);
ipv.setHopLimit(255);
ipv.setSourceAddress(self.getAddress());
ipv.setSourceAddress(getSelf().getAddress());
ipv.setDestinationAddress(addr);
ipv.setPriority(packet.getPriority());
if(packet instanceof DATATPacket) {
ipv.setPromise(true);
}
ipv.enableECN();
/* if(b)
ipv.markCE();*/
ipv.setPayload(packet);
//System.out.println(ipv.getPayload().getProtocolNumber());
/*System.out.println("SND:"+ipv.getPayload().getData());
@@ -828,13 +754,12 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
System.out.println(Arrays.toString(b));*/
//packet.getSendRecord().add(null);
packet.incSendCounter();
}finally {
packet.getDisposeLock().unlock();
}
packet.putTimePassport("packedInIPv6");
packet.printPassport();
ipv.putTimePassport("packed");
srv6Router.putProtocolNumberPacketAndInsertSRH(ipv);
srv6Router.insertSRHandRoutePacket(ipv);
//srv6Router.putProtocolNumberPacketAndInsertSRHAsync(ipv);
});
}
@@ -869,7 +794,11 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
try {
BandwidthDistributer<PortPair> bdr= bandwidthDistrmap.get(targetaAddress);
if(bdr==null) {
bandwidthDistrmap.put(targetaAddress, bdr=new BandwidthDistributer<>(1024*20000L*1024));
bdr=new BandwidthDistributer<>(1024*20000L*1024);
bdr.setTotalRequestUpdateConsumer((treq)->{
KLALBRoutingProtocol krp= srv6Router.getKlalbRouteProtol();
krp.updateTotalRequestBandwidth(targetaAddress,treq);});
bandwidthDistrmap.put(targetaAddress, bdr);
}
bdr.setDistrUpdateConsumer(portp, updateConsumer);
@@ -920,7 +849,6 @@ private List<MultipurposeSocketAddress> listens=new CopyOnWriteArrayList<>();
}
/*@Override
public void listen(MultipurposeSocketAddress msa) {
// TODO 自动生成的方法存根
@@ -8,10 +8,18 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.StreamCorruptedException;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import org.kne.cloud.network.NetworkPacket;
import org.kne.io.KNEChannels;
public class KLALBInputStream extends DataInputStream {
private ReadableByteChannel channel;
public KLALBInputStream(InputStream in) throws IOException {
super(in);
channel=Channels.newChannel(in);
byte[]b=new byte[5];
readFully(b);
String s=new String(b,"ascii");
@@ -23,8 +31,16 @@ public class KLALBInputStream extends DataInputStream {
if(bv!=CONST.bversion)
throw new StreamCorruptedException("remote version is V"+bv+"."+sv+",not V"+CONST.klalbver);
}
public KLALBPacket readPacket() throws IOException {
public KLALBPacket readKLALBPacket() throws IOException {
int len=readInt();
return KLALBPacket.readKLALBPacketFromStream(this);
}
public ByteBuffer readPacket() throws IOException {
int len=readInt();
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(len);
bbf.limit(len);
KNEChannels.readFully(channel, bbf);
return bbf;
}
}
+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.UIEnv;
import org.kne.cloud.network.perf.Kperf;
import org.kne.cloud.network.perf.MemcpyBenchmark;
import org.kne.cloud.network.perf.NodeBenchmark;
import org.kne.debug.Debuger;
public class KLALBMain {
@@ -37,7 +39,7 @@ public class KLALBMain {
KLALBProxySystem kpcje=new KLALBProxySystem();
kpcje.loadConfigJson(configJson);
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getHostAddress());
System.out.println("SRv6地址:"+kpcje.getKlalbController().getSelf().getAddress().getHostAddress());
try {
openGUI(kpcje);
}catch(RuntimeException e) {
@@ -152,10 +154,40 @@ public class KLALBMain {
System.out.println("请输入测速服务端地址:端口!");
}
break;
case "memcpy":
System.out.println("数组拷贝测试");
for (int i = 0; i < 10; i++) {
MemcpyBenchmark. testArrayCopySpeed(256*1024*1024);
}
System.out.println("Bytebuffer拷贝测试");
for (int i = 0; i < 10; i++) {
MemcpyBenchmark.testByteBufferCopySpeed(256*1024*1024);
}
System.out.println("Directbytebuffer分配测试");
for (int i = 0; i < 10; i++) {
MemcpyBenchmark.testDirectByteBufferAllocateSpeed(65536);
}
System.out.println("Bytebuffer分配测试");
for (int i = 0; i < 10; i++) {
MemcpyBenchmark.testByteBufferAllocateSpeed(65536);
}
System.out.println("BytebufferAllocator分配测试");
for (int i = 0; i < 10; i++) {
MemcpyBenchmark.testByteBufferAllocatorSpeed(65536);
}
break;
//case "$$SYSTEM:":
//System.out.println();
//break;
case "nodebenchmark":
int nodenumber=100;
if(sc.length>=2) {
nodenumber=Integer.parseInt(sc[1]);
}
NodeBenchmark nbc=new NodeBenchmark(kpcje.getKlalbController(),nodenumber);
nbc.startPerfing();
break;
default:
System.out.println("未知命令,请输入help以查询命令说明");
}
@@ -4,19 +4,29 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
public class KLALBOutputStream extends DataOutputStream {
private WritableByteChannel channel;
public KLALBOutputStream(OutputStream out) throws IOException {
super(out);
this.channel=Channels.newChannel(out);
byte[]b=new byte[] {'K','L','A','L','B'};
write(b);
writeInt(CONST.bversion);
writeInt(CONST.sversion);
flush();
}
public void writePacket(KLALBPacket klb) throws IOException {
public void writeKLALBPacket(KLALBPacket klb) throws IOException {
writeInt((int) klb.getLength());
KLALBPacket.writeKLALBPacketToStream(this, klb);
}
public void writePacket(ByteBuffer kp) throws IOException {
writeInt( kp.limit());
channel.write(kp);
}
}
@@ -4,6 +4,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
@@ -15,6 +16,8 @@ import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.perf.TEST1Packet;
import org.kne.cloud.network.perf.TESTNPacket;
public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public static final int KLALB_PROTOCOL_NUMBER=254;
@@ -32,12 +35,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public static final int VADDR=8;
public static final int ADDLINES=9;
public static final int NACKT=10;
public static final int TEST=11;
public static final int TESTN=11;
public static final int VADDRACK=12;
public static final int VADDRREQ=13;
public static final int IPV6OVERKLALB=14;
public static final int ADDR=15;
public static final int ADDRREQ=16;
public static final int TEST1=17;
//private static final int HEADER_CAPACITY = 32;
@@ -45,7 +49,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
//public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192);
protected volatile ByteBuffer klalbHeader;
protected ByteBuffer klalbHeader;
protected KLALBPacket(ByteBuffer klalbHeader,int headerLength) {
super(KLALB_PROTOCOL_NUMBER,false);
@@ -55,7 +59,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public KLALBPacket(int type,int headerLength) {
super(KLALB_PROTOCOL_NUMBER,false);
klalbHeader=ByteBuffer.allocate(headerLength);
klalbHeader=NetworkPacket.bufferAllocator.allocate(headerLength);
klalbHeader.put((byte) type);
this.headerLength=headerLength;
}
@@ -83,7 +87,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return joinqueuetime;
}
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
sndtime=System.nanoTime();
dto.write(klalbHeader.slice(0, headerLength));
}
@@ -93,7 +97,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return false;
}
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
klalbHeader.limit(headerLength);
while(klalbHeader.hasRemaining()){
if(din.read(klalbHeader)==-1) {
@@ -135,13 +139,6 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return klalbHeader;
}
public void dispose() {
super.dispose();
/* ByteBuffer datax=klalbHeader;
klalbHeader=null;
if(datax!=null)
KLALBPacket.databufferpool_40.back(datax);*/
}
public static KLALBPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
return readKLALBPacketFromChannel(Channels.newChannel(in));
@@ -149,14 +146,14 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
public static KLALBPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
while(true) {
ByteBuffer bb=databufferpool_40.borrow();
ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
bb.limit(1);
while(bb.hasRemaining()){
if(in.read(bb)==-1) {
return null;
}
}
int type=bb.get(0);
int type=bb.get(0)&0xff;
bb.limit(bb.capacity());
KLALBPacket klp;
@@ -196,8 +193,8 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
klp=new NACKTPacket(bb);
klp.readFromChannel(in);
return klp;
case TEST:
klp=new TESTPacket(bb);
case TESTN:
klp=new TESTNPacket(bb);
klp.readFromChannel(in);
return klp;
case VADDRACK:
@@ -220,9 +217,13 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
klp=new ADDRREQPacket(bb);
klp.readFromChannel(in);
return klp;
case TEST1:
klp=new TEST1Packet(bb);
klp.readFromChannel(in);
return klp;
}
//throw new StreamCorruptedException("unknown package type:"+type);
System.err.println("ignore unknown KLALBPacket type:"+type);
throw new StreamCorruptedException("unknown package type:"+type);
//System.err.println("ignore unknown KLALBPacket type:"+type);
}
}
@@ -237,10 +238,7 @@ public abstract class KLALBPacket extends IPv6Packet.IPv6Payload {
return null;
}
public void doDisposeAfterSend() {
if(isDisposeAfterSend())
dispose();
}
private boolean ce=false;
public void setCE(boolean ce) {
this.ce=ce;
@@ -2,13 +2,26 @@ package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.MultipurposeSocketAddress;
public interface KLALBPacketLink {
public void writePacket(KLALBPacket kp) throws IOException;
public void setOutputTrafficCounters(AtomicLong[] al);
public void setOutputPacketsCounters(AtomicLong[] al);
public void setInputTrafficCounters(AtomicLong[] al);
public void setInputPacketsCounters(AtomicLong[] al);
public void writePacket(ByteBuffer kp) throws IOException;
public default void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
for (int i = 0; i < len; i++) {
writePacket(kpp[off+i]);
}
}
public void writeKLALBPacket(KLALBPacket kp) throws IOException;
public void flush() throws IOException;
public KLALBPacket readPacket()throws IOException;
public KLALBPacket readKLALBPacket()throws IOException;
public ByteBuffer readPacket()throws IOException;
public void close() throws IOException;
public boolean isClosed();
public void setSoTimeout(int val) throws SocketException;
@@ -11,11 +11,13 @@ import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -112,15 +114,43 @@ public class KLALBProxySystem {
case "KLALBController":
JsonElement vase= entry.get("VirtualAddress");
//System.out.println(vase);
List<InetAddress>daddr=new ArrayList<InetAddress>();
JsonElement vdns= entry.get("DNS");
if(vdns!=null) {
if(vdns instanceof JsonArray) {
JsonArray arr=(JsonArray) vdns;
for(JsonElement str:arr) {
try {
daddr.add((Inet6Address) InetAddress.getByName(str.getAsString()));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}else {
try {
daddr.add((Inet6Address) InetAddress.getByName(vdns.getAsString()));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
if(vase!=null) {
try {
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()));
klalbController=new KLALBController((Inet6Address) InetAddress.getByName(vase.getAsString()),daddr);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}else {
klalbController=new KLALBController();
klalbController=new KLALBController(daddr);
}
JsonElement vasn= entry.get("VirtualASN");
if(vasn!=null) {
klalbController.getIpv6Router().setASN (Long.parseLong( vasn.getAsString()));
}
JsonElement vsne=entry.get("VirtualSocketName");
//if(vsne!=null) {
MultipurposeSocketAddress.getSocketTypeRegister().put(vsne.getAsString(), klalbController.getSocketType());
@@ -280,7 +310,7 @@ public class KLALBProxySystem {
if(string.startsWith("SocketBridge")) {
return new DefaultSocketBridgeFactory();
}else if(string.startsWith("MinecraftSocketBridge")) {
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf(), Integer.parseInt(string.substring(21)));
return new DefaultMinecraftSocketBridgeFactory(klalbController.getSelf().getAddress(), Integer.parseInt(string.substring(21)));
}
throw new IllegalArgumentException("unknown SocketBridge type:"+string);
}
@@ -5,42 +5,69 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StreamCorruptedException;
import java.lang.foreign.MemorySegment;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.UnresolvedAddressException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.kne.cloud.clock.AdjustedNanoClock;
import org.kne.cloud.clock.ReliabilityBackoffTimeClock;
import org.kne.cloud.network.ByteBufferAllocator;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6EmptyPayload;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.ipv6.RouteItem;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.NanoTimeSeries;
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.perf.TESTNPacket;
import org.kne.cloud.network.srv6.ACKSEQSSegmentRoutingTLV;
import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV;
import org.kne.cloud.network.srv6.SEQSSegmentRoutingTLV;
import org.kne.cloud.network.te.BandwidthDistributer;
import org.kne.cloud.network.te.LoadingBalanceEntry;
import org.kne.concurrent.DisruptorExecutor;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> ,LoadingBalanceEntry<KLALBRemoteLine>{
public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteLine> {
private static final int HEADER_CALIBRATE = 40;
private static final boolean debug = false;
private static final boolean showpacket = false;
@@ -221,10 +248,19 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}
private static long MIN_SPEED=256*1024L;
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,10000000L);
private SpeedLimiter congress = new SpeedLimiter(MIN_SPEED,20*1000000L);//50*1000000L
private long congressSpeed = 0;
private double loadPercent = 1.01;
private double burstPercent = 1.3;//10.0
private double windowPercent = 2;
private long MIN_RTTVAR=25000000L;
private AtomicBoolean firstUpdate=new AtomicBoolean(true);
private volatile long RTTMin=1000000000L;
private volatile long RTTVar=1000000000L;
private volatile long RTTAvg=1000000000L;
private volatile long RTO=1000000000L;
protected void startIO() {
ThreadTool.makeVDaemonThreadIfSupport("远程接收线程", () -> {
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
@@ -251,87 +287,153 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
addressGroup=new Inet6AddressGroup(i6a, 112);
}
} else {
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress);
kplink = KLALBUtils. createKLALBPacketLink(bindAddress, socketAddress,false);
}
//startRecord();
if (klalbController != null) {
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL(),klalbController.getLinkMonitor().getInTrafficAL()});
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL(),klalbController.getLinkMonitor().getOutTrafficAL()});
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL(),klalbController.getLinkMonitor().getInPacketCounterAL()});
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL(),klalbController.getLinkMonitor().getOutPacketCounterAL()});
} else {
kplink.setInputTrafficCounters(new AtomicLong[] {monitor.getInTrafficAL()});
kplink.setOutputTrafficCounters(new AtomicLong[] {monitor.getOutTrafficAL()});
kplink.setInputPacketsCounters(new AtomicLong[] {monitor.getInPacketCounterAL()});
kplink.setOutputPacketsCounters(new AtomicLong[] {monitor.getOutPacketCounterAL()});
}
kplink.setSoTimeout(20000);
if(kplink.isStream()) {
windowPercent=1.4;
MIN_RTTVAR=50000000;
burstPercent=2.0;//1.5
//ackInterval=10000000L;
}else {
windowPercent=1.2;
MIN_RTTVAR=20000000;
burstPercent=2.0;
//ackInterval=1000000L;
}
Thread timer = ThreadTool.makeVDaemonThread("重路由计时器线程", () -> {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
while((!kplink.isClosed()) && (!closed)) {
Collection<SendItem>vals= sendMap.values();
for (Iterator<SendItem> iterator = vals.iterator(); iterator.hasNext();) {
SendItem sitm = (SendItem) iterator.next();
if(System.nanoTime() -sitm.getSendtime()>RTO) {
iterator.remove();
sendmapWindowUsed.addAndGet((int) -(sitm.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
//if(!kplink.isStream())
if(sitm.getPacket().isPromise()) {
IPv6Packet pktr=sitm.getPacket();
pktr.setPriority(pktr.getPriority()-1);
rerouteConsumer.accept(pktr);
}
//System.out.println("reroute");
}
}
for (Iterator<Entry<UUID, Long>> iterator = recvedUIDMap.entrySet().iterator(); iterator.hasNext();) {
Entry<UUID, Long> sendItem = (Entry<UUID, Long>) iterator.next();
if(System.nanoTime()-sendItem.getValue()>10000000000L) {
iterator.remove();
}
}
if(checkACKTime()) {
sendALLIPv6ACK();
//System.out.println("ACK发送");
}
try {
Thread.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
timer.start();
Thread t = ThreadTool.makeVDaemonThreadIfSupport("远程发送线程", () -> {
tlock = Thread.currentThread();
//tlock.setPriority(Thread.NORM_PRIORITY+1);
try {
writePacketToKPL(new ADDRREQPacket());
writePacketToKPL(new ADDRREQPacket());
writeKLALBPacketToKPL(new ADDRREQPacket());
writeKLALBPacketToKPL(new ADDRREQPacket());
if(addressGroup!=null) {
writePacketToKPL(new ADDRPacket(addressGroup));
writePacketToKPL(new ADDRPacket(addressGroup));
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
writeKLALBPacketToKPL(new ADDRPacket(addressGroup));
}
writePacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRREQPacket());
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
writePacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
writeKLALBPacketToKPL(new VADDRREQPacket());
writeKLALBPacketToKPL(new VADDRREQPacket());
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
writeKLALBPacketToKPL(new VADDRPacket(localVaddrSupplier.get()));
flushKPL();
KLALBPacket kpp = null;
ByteBuffer[] kpp = null;
int kppslen=0;
while ((!kplink.isClosed()) && (!closed)) {
// TimeDebugger tdb=new TimeDebugger();
// tdb.putTime("start");
if(checkBandwidthReportTime()) {
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
sendIPacket(new BWINFPacket(monitor.getOutSpeedAvg(), monitor.getInSpeedAvg()));
}
if (checkPingTimeSleep()) {
writePacketToKPL(new PINGPacket(System.nanoTime()));
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
if (remoteVaddr == null)
writePacketToKPL(new VADDRREQPacket());
writeKLALBPacketToKPL(new VADDRREQPacket());
if(peerAddress==null)
writePacketToKPL(new ADDRREQPacket());
writeKLALBPacketToKPL(new ADDRREQPacket());
}else {
KLALBPacket kpip = IsendDequeList.poll();
if (kpip != null) {
writePacketToKPL(kpip);
writeKLALBPacketToKPL(kpip);
}else {
// tdb.putTime("Isend");
if (kpp == null) {
do {
kpp = sendDequeList.poll();
} while (kpp != null && kpp.isDisposed());
if(kpp==null) {
ByteBuffer tkpp = sendDequeList.poll();
if(tkpp==null) {
monitor.setQueueingDelay(0);
}else {
kpp=new ByteBuffer[10];
kpp[0]=tkpp;
int i=1;
for(;i<kpp.length;i++) {
ByteBuffer xkpp=sendDequeList.poll();
if(xkpp==null)
break;
kpp[i]=xkpp;
}
kppslen=i;
}
}
// System.out.println(sendDequeList.size());
if (kpp != null) {
// TimeDebugger tdb=new TimeDebugger();
//tdb.putTime("start");
KLALBPacket kppt=kpp;
kppt.lockAll();
try {
if (kpp.isSomeDisposed()) {
kpp = null;
} else {
// if (congress.checkTransmit(length)) {
writePacketToKPL(kpp);
kplink.writePackets(kpp,0,kppslen);
if (checkPingTime()) {
writePacketToKPL(new PINGPacket(System.nanoTime()));
writeKLALBPacketToKPL(new PINGPacket(System.nanoTime()));
}
monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
//monitor.setQueueingDelay( System.nanoTime()- kpp.getJoinqueuetime());
/*if (kpp instanceof DATATPacket||kpp instanceof IPv6OverKLALBPacket) {
resetSleepTimer();
}*/
kpp.doDisposeAfterSend();
kpp = null;
}
//}
} finally {
kppt.unlockAll();
}
//tdb.putTime("sendToLink");
//tdb.print();
}else {
LockSupport.parkNanos(1000000);
LockSupport.parkNanos(10000000L);
}
}
}
@@ -358,6 +460,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
// System.out.println(sendDequeList.isEmpty());
Thread.yield();
}
}catch(StreamCorruptedException sce) {
sce.printStackTrace();
} catch (IOException | UnresolvedAddressException e) {
if (debug)
e.printStackTrace();
@@ -370,28 +474,26 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}
});
t.start();
boolean fst = true;
AtomicBoolean fst = new AtomicBoolean(true);
long stime = 5000000000L;
while ((!kplink.isClosed()) && (!closed)) {
long readStart = System.nanoTime();
KLALBPacket kpp = readPacketFromKPL();
/*long readTime = System.nanoTime() - readStart;
readTime *= 10;
if (readTime > stime) {
stime = readTime;
} else {
stime = (stime * 999 + readTime) / 1000;
}
if (stime < 2000000000L) {
stime = 2000000000L;
}*/
// System.out.println(readTime);
ByteBuffer kppb = kplink.readPacket();
kplink.setSoTimeout(3000);
kplink.setSoTimeout((int) (stime / 1000000));
if (kpp == null) {
if (kppb == null) {
break;
}
HighPerformanceExecutor.defaultExecutor.execute(()->{
KLALBPacket kpp=null;
try {
kpp = KLALBPacket.readKLALBPacketFromChannel(KNEChannels.newReadableChannel(kppb));
} catch (IOException e) {
e.printStackTrace();
}
if(kpp==null)
return;
debugShowPacket("RX",kpp);
switch (kpp.getType()) {
case KLALBPacket.PING:
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
@@ -404,29 +506,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
long DsndDelayFactor;
long DrcvDelayFactor;
adjnc.getLock().lock();
AdjustedNanoClock adjc=adjnc;
adjc.getLock().lock();
try {
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
adjc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
if (DsndDelayFactor < 0) {
if (DrcvDelayFactor < 0) {
} else {
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
adjc.setDelta(adjc.getDelta() + DsndDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
}
} else {
if (DrcvDelayFactor < 0) {
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
adjc.setDelta(adjc.getDelta() - DrcvDelayFactor);
DsndDelayFactor = DsndDelayFactor0 - adjc.getDelta();
DrcvDelayFactor = DrcvDelayFactor0 + adjc.getDelta();
}
}
} finally {
adjnc.getLock().unlock();
adjc.getLock().unlock();
}
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
@@ -436,7 +539,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
//pingInterval = monitor.getLatencyAvg()+2000000L;
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
loadPercent =Math.max( 1.2,0.4);
//loadPercent =Math.max( 1.3,0.4);
}
LockSupport.unpark(tlock);
@@ -446,9 +549,12 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if (bwi.getDownSpeed() >= congressSpeed) {
congressSpeed = bwi.getDownSpeed();
} else {
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
congressSpeed = (congressSpeed * 199 + bwi.getDownSpeed()) / 200;
}
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
bandwidthDistributer.setTotalBandwidth (congressSpeed );
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * burstPercent)) );
//reallimit=(int) (congress.getLimitspeed()*monitor.getLatencyMin()/1000000000L);
reallimit=(int) (Math.max(MIN_SPEED,(long) (congressSpeed*windowPercent ))*Math.max(2000000L,RTTMin)/1000000000L);
// System.out.println(congressSpeed);
break;
case KLALBPacket.ADDRREQ:
@@ -460,7 +566,13 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if(addressGroup==null) {
byte[]ab=peerAddress.getAddress().getAddress();
ab[15]=2;
Inet6AddressGroup ardg2=new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
Inet6AddressGroup ardg2=null;
try {
ardg2 = new Inet6AddressGroup((Inet6Address) InetAddress.getByAddress(ab),peerAddress.getPrefixLength());
} catch (UnknownHostException e) {
e.printStackTrace();
}
if(ardg2!=null)
addressGroup=ardg2;
}
break;
@@ -475,39 +587,124 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
if (klalbController != null) {
adjnc = klalbController.getAdjustedClockByVaddr(remoteVaddr.getAddress());
}
if (fst) {
if (fst.compareAndSet(true, false)) {
// coll.resetCoolingTime();
monitor.setState(MonitorData.ONLINE);
fst = false;
}
break;
case KLALBPacket.VADDRACK:
break;
case KLALBPacket.TEST:
case KLALBPacket.TESTN:
break;
case KLALBPacket.IPV6OVERKLALB:
if(ipv6con!=null) {
IPv6OverKLALBPacket ivk=(IPv6OverKLALBPacket) kpp;
IPv6Packet iv6= ivk.getIPv6Packet();
ivk.putTimePassport("unpacked");
ivk.printPassport();
iv6.putTimePassport("unpackFromLink");
IPSequence val=null;
IPv6SegmentRoutingHeader srh= iv6.getSRHHeader();
if(srh!=null) {
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
for (int i = 0; i < l.size(); i++) {
IPv6SegmentRoutingTLV tlv=l.get(i);
if(tlv instanceof SEQSSegmentRoutingTLV) {
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
// if(seqs.isPromise()) {
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
//}
}else if(tlv instanceof ACKSEQSSegmentRoutingTLV) {
ACKSEQSSegmentRoutingTLV aseq=(ACKSEQSSegmentRoutingTLV) tlv;
l.remove(i);
i--;
SendItem ipv6;
if((ipv6=sendMap.remove(aseq.getIPSequence()))!=null) {
sendmapWindowUsed.addAndGet((int) -(ipv6.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
long RTTC=System.nanoTime()-ipv6.getSendtime();
if(RTTC<=RTTMin) {
RTTMin=RTTC;
}else {
RTTMin= (RTTMin*99999+RTTC)/100000;
}
if(firstUpdate.compareAndSet(true, false)) {
RTTAvg=RTTC;
RTTVar=RTTC/2;
}else {
RTTVar=(RTTVar*3+Math.abs(RTTAvg-RTTC))/4;
RTTAvg= (RTTAvg*7+RTTC)/8;
}
RTO=RTTAvg+Math.max(MIN_RTTVAR, RTTVar*4);//RTTVar*4
//System.out.println("remove:"+aseq.getSequence()+" "+sendMap.size());
}else {
// System.out.println("miss:"+aseq.getSequence()+" "+sendMap.size());
}
}
}
}
if(val!=null)
ackIDs.add(val);
/*if(val!=null&&peerAddress!=null) {
UUID val2=val;
HighPerformanceExecutor.defaultExecutor.execute(()->{
IPv6Packet ipv=new IPv6Packet();
ipv.setVersion(6);
ipv.setTrafficClass(0);
ipv.setFlowLabel(0);
ipv.setHopLimit(255);
ipv.setSourceAddress(addressGroup.getAddress());
ipv.setDestinationAddress(peerAddress.getAddress());
ipv.setPriority(0);
ipv.enableECN();
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
srh2.getAddresses().add(peerAddress.getAddress());
srh2.getTlvs().add(new ACKSEQSSegmentRoutingTLV(val2,true));
ipv.getHeaders().add(srh2);
ipv.setPayload(new IPv6EmptyPayload());
sendIPacket(new IPv6OverKLALBPacket( ipv));
//System.out.println("ack:"+val);
});
}*/
if(ipv6con!=null) {
if(iv6.getPayload()instanceof IPv6EmptyPayload) {
//iv6.dispose();
}else {
if(val!=null) {
Long l=recvedUIDMap.putIfAbsent(val.getUuid(), System.nanoTime());
if(l==null) {
ipv6con.accept(iv6);
}else {
//System.out.println("虚假重传:"+val.getUuid());
}
}else {
ipv6con.accept(iv6);
}
}
}
break;
default:
while (rec == null) {
Thread.sleep(1);
}
if(rec!=null)
rec.accept( kpp);
break;
}
});
Thread.yield();
}
}catch(StreamCorruptedException sce) {
sce.printStackTrace();
} catch (IOException | UnresolvedAddressException e) {
if (debug)
e.printStackTrace();
} catch (InterruptedException e) {
}catch(Exception e) {
e.printStackTrace();
} finally {
monitor.setState(MonitorData.OFFLINE);
@@ -518,17 +715,14 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
} catch (IOException e) {
e.printStackTrace();
}
/*KLALBPacket pack;
while((pack=sendDequeList.poll())!=null) {
try {
if(remoteVaddr!=null) {
klalbController.sendPacketToLinkAddress(remoteVaddr, pack);
if(debug)
System.out.println("RETRY:"+pack);
}
} catch (IOException e) {
Collection<SendItem>vals= sendMap.values();
SendItem[]packs= vals.toArray(new SendItem[0]);
for (SendItem iPv6Packet : packs) {
rerouteConsumer.accept(iPv6Packet.getPacket());
//System.out.println("重路由:"+iPv6Packet);
}
}*/
sendMap.clear();
sendmapWindowUsed.set(0);
}
if (closed) {
@@ -544,63 +738,98 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}).start();
}
private ConcurrentLinkedQueue<IPSequence> ackIDs=new ConcurrentLinkedQueue<>();
private volatile long prevAckTime=System.nanoTime();
private volatile long ackInterval=1000000L;
private boolean checkACKTime() {
long cu = System.nanoTime();
if (cu - prevAckTime > ackInterval) {
prevAckTime = cu;
return true;
} else {
return false;
}
}
private void sendALLIPv6ACK() {
if(peerAddress!=null) {
while(true) {
int rez=sendIPv6ACK();
if(rez<=0)
break;
}
}
}
private int sendIPv6ACK() {
IPv6SegmentRoutingHeader srh2=new IPv6SegmentRoutingHeader();
int adds=addACKSEQToSRH(srh2,40);
if(adds<=0)
return adds;
//System.out.println(adds+"ACKS");
IPv6Packet ipv=new IPv6Packet();
ipv.setVersion(6);
ipv.setTrafficClass(0);
ipv.setFlowLabel(0);
ipv.setHopLimit(255);
ipv.setSourceAddress(addressGroup.getAddress());
ipv.setDestinationAddress(peerAddress.getAddress());
ipv.setPriority(0);
ipv.enableECN();
srh2.getAddresses().add(peerAddress.getAddress());
ipv.getHeaders().add(srh2);
ipv.setPayload(new IPv6EmptyPayload());
sendIPacket(new IPv6OverKLALBPacket( ipv));
//System.out.println("ack:"+val);
return adds;
}
private int addACKSEQToSRH(IPv6SegmentRoutingHeader srh,int maxAckCount){
int i = 0;
for (; i < maxAckCount; i++) {
IPSequence ackid= ackIDs.poll();
if(ackid!=null) {
srh.getTlvs().add(new ACKSEQSSegmentRoutingTLV(ackid, ackid.isPromise()));
}else {
prevAckTime=System.nanoTime();
return i;
}
}
return i;
}
private void flushKPL() throws IOException {
kplink.flush();
}
private KLALBPacket readPacketFromKPL() throws IOException {
KLALBPacket packet = kplink.readPacket();
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.out.println("RX:" + packet);
}
private KLALBPacket readKLALBPacketFromKPL() throws IOException {
KLALBPacket packet = kplink.readKLALBPacket();
debugShowPacket("RX",packet);
if (packet != null) {
packet.putTimePassport("received");
long length=packet.getLength();
monitor.getInTrafficAL().addAndGet(length);
monitor.getInPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getInTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getInPacketCounterAL().incrementAndGet();
}
return packet;
}
private void writePacketToKPL(KLALBPacket packet) throws IOException {
long length=packet.getLength();
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
private void writeKLALBPacketToKPL(KLALBPacket packet) throws IOException {
kplink.writeKLALBPacket(packet);
packet.putTimePassport("sended");
packet.printPassport();
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.err.println("TX:" + packet);
}
debugShowPacket("TX",packet);
}
private void writePacketToKPL(KLALBPacket packet,long length) throws IOException {
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
if (klalbController != null)
klalbController.getLinkMonitor().getOutTrafficAL().addAndGet(length);
klalbController.getLinkMonitor().getOutPacketCounterAL().incrementAndGet();
kplink.writePacket(packet);
private void debugShowPacket(String label, KLALBPacket packet) {
if (showpacket) {
if (!(packet instanceof PINGPacket))
if (!(packet instanceof PONGPacket))
if (!(packet instanceof BWINFPacket))
System.err.println("TX:" + packet);
System.err.println(label+":" + packet);
}
}
@@ -622,7 +851,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private volatile long time = System.nanoTime();
private volatile long pingInterval = 10000000L;
private volatile long pingIntervalSleep = 200000000L;
private volatile long pingIntervalSleep = 500000000L;
private boolean checkPingTime() {
long cu = System.nanoTime();
@@ -649,7 +878,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private volatile long bwtime = System.nanoTime();
private volatile long bwpingInterval = 10000000L;
private volatile long bwpingIntervalSleep = 100000000L;
private volatile long bwpingIntervalSleep = 200000000L;
private boolean checkBandwidthReportTime(){
long cu = System.nanoTime();
if (cu - bwtime > bwpingIntervalSleep) {
@@ -667,16 +896,25 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
private PriorityBlockingQueue<ByteBuffer> sendDequeList = new PriorityBlockingQueue<ByteBuffer>();
public PriorityBlockingQueue<KLALBPacket> getQueue() {
public PriorityBlockingQueue<ByteBuffer> getQueue() {
return sendDequeList;
}
protected void sendPacket(KLALBPacket blk) {
debugShowPacket("TX",blk);
blk.markJoinqueuetime();
sendDequeList.add(blk);
ByteBuffer buf=NetworkPacket.bufferAllocator.allocate((int) blk.getLength());
try {
KLALBPacket.writeKLALBPacketToChannel(KNEChannels.newWritableChannel(buf), blk);
buf.flip();
sendDequeList.add(buf);
LockSupport.unpark(tlock);
} catch (IOException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
}
private void sendIPacket(KLALBPacket blk) {
@@ -688,21 +926,8 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
this.rec = rec;
}
/*public void remoeFromSendQueue(KLALBPacket klalbPacket) {
sendDequeList.remove(klalbPacket);
}*/
public long statLengthBefore(long l) {
AtomicLong al = new AtomicLong();
for (Iterator<KLALBPacket> iterator = sendDequeList.iterator(); iterator.hasNext();) {
KLALBPacket queue = iterator.next();
if (queue.getPriority() <= l) {
al.addAndGet(queue.getLength());
}
}
return al.get();
}
private volatile long predictTime;
@@ -744,7 +969,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}
}
private static final TESTPacket testPacket = new TESTPacket(60000);
private static final TESTNPacket testPacket = new TESTNPacket(60000);
private volatile boolean pressure = false;
private SpeedLimiter pressureSpeed = new SpeedLimiter(32768);
@@ -774,46 +999,21 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
return predictTime;
}
private List<Double>ranks=new ArrayList<Double>();
private Consumer<IPv6Packet> ipv6con;
@Override
public void noticeRank(int rank) {
while(rank>=ranks.size()) {
ranks.add(0.5);
}
for (int i = 0; i < ranks.size(); i++) {
if(i==rank) {
ranks.set(i, (ranks.get(i)*99.0+1.0D)/100.0);
}else {
ranks.set(i, ranks.get(i)*99.0/100.0);
}
}
}
@Override
public double getWeightAtRank(int rank) {
while(rank>=ranks.size()) {
ranks.add(0.5);
}
return ranks.get(rank);
}
public List<Double> getRanks() {
return ranks;
}
@Override
public boolean isLoopBack() {
return false;
}
private BandwidthDistributer<Inet6Address> bandwidthDistributer=new BandwidthDistributer<Inet6Address>();
@Override
public List<Neighbor> getNeighborsInfo() {
List<Neighbor>hs=new ArrayList<>();
if(peerAddress!=null) {
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor));
hs.add(new Neighbor(peerAddress, remoteVaddr, monitor,bandwidthDistributer));
//System.out.println(peerAddress+" "+addressGroup);
}
return hs;
@@ -821,26 +1021,77 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
private Map<IPSequence,SendItem> sendMap= new ConcurrentHashMap<>();
private AtomicInteger sendmapWindowUsed=new AtomicInteger(0);
private Map<UUID,Long>recvedUIDMap=new ConcurrentHashMap<UUID, Long>();
private volatile int inputchachesize = 8192 * 4000;
private volatile int outputchachesize = 8192 * 240;//500
private volatile int reallimit = 65536 ;
private Consumer<IPv6Packet> rerouteConsumer;
@Override
public void sendPacket(IPv6Packet pack, Inet6Address inet6Address) throws IOException {
pack.lockAll();
try {
if(pack.isSomeDisposed()) {
return;
//只有已连接的链路才能传输数据
if(monitor.getState()==MonitorData.ONLINE) {
//if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
//获得数据包的SRv6扩展头部
IPv6SegmentRoutingHeader srh= pack.getSRHHeader();
IPSequence val=null;
if(srh!=null) {
List<IPv6SegmentRoutingTLV> l=srh.getTlvs();
for (int i = 0; i < l.size(); i++) {
IPv6SegmentRoutingTLV tlv=l.get(i);
if(tlv instanceof SEQSSegmentRoutingTLV) {
SEQSSegmentRoutingTLV seqs=(SEQSSegmentRoutingTLV) tlv;
//if(seqs.isPromise())
//获得数据包的序号
val=new IPSequence(seqs.getUUID(),seqs.isPromise());
break;
}
}
if(val!=null) {
//放入滑动窗口中并记录缓冲区大小占用
SendItem old= sendMap.put(val,new SendItem( pack));
if(old!=null) {
sendmapWindowUsed.addAndGet((int) -(old.getPacket().getPayload().getLength()+HEADER_CALIBRATE));
}
sendmapWindowUsed.addAndGet((int) (pack.getPayload().getLength()+HEADER_CALIBRATE));
//System.out.println("add: "+ val+" "+sendMap.size());
}
}
//捎带发送反方向的ACK给对方发送过来的数据包减小设备性能开销
if(srh!=null) {
addACKSEQToSRH(srh,10);
}
//发送数据包
sendIPv6PacketToLink(pack);
//}
}else {
if(rerouteConsumer!=null) {
rerouteConsumer.accept(pack);
}
}
if(inet6Address.equals(remoteVaddr.getAddress())||inet6Address.equals(peerAddress.getAddress())) {
}
@Override
public void setRerouteConsumer(Consumer<IPv6Packet> rerouteConsumer) {
this.rerouteConsumer=rerouteConsumer;
}
private void sendIPv6PacketToLink(IPv6Packet pack) {
IPv6OverKLALBPacket kipv6=new IPv6OverKLALBPacket(pack);
kipv6.setPriority(pack.getPriority());
kipv6.setDisposeAfterSend(true);
pack.putTimePassport("packdInLink");
pack.printPassport();
sendPacketToLink(kipv6);
}
}finally {
pack.unlockAll();
}
}
private void sendPacketToLink(KLALBPacket packet) {
@@ -850,13 +1101,18 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
}
@Override
public boolean isCongress(IPv6Packet iPv6Packet) {
int size=getQueue().size();
if(size>30) {
public boolean isCongress(IPv6Packet iPv6Packet,double scale) {
if(monitor.getInDelay()>3000000000L||monitor.getOutDelay()>3000000000L||monitor.getInSpeedAvg()<=0||monitor.getOutSpeedAvg()<=0)
return true;
}else {
return !congress.checkTransmit(iPv6Packet.getLength());
}
boolean congress=sendmapWindowUsed.get()>reallimit*scale;
return congress;
}
@Override
public boolean isReachSpeedLimit(IPv6Packet iPv6Packet) {
boolean xcongress=!congress.checkTransmit(iPv6Packet.getLength());
return xcongress;
}
@Override
@@ -879,6 +1135,30 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable<KLALBRemoteL
this.ipv6con=ipv6con;
}
@Override
public List<RouteItem> getRouteItems() {
List<RouteItem> rlist=new ArrayList<>();
Inet6AddressGroup adg=addressGroup;
if(adg!=null)
rlist.add(new RouteItem(new Inet6AddressGroup(adg.getAddress(), 128),
adg.getAddress(), this, "Direct", 0, 0, null, "D",true));
for (Iterator<Neighbor> iteratorx = getNeighborsInfo()
.iterator(); iteratorx.hasNext();) {
Neighbor addresses = (Neighbor) iteratorx.next();
RouteItem ri = new RouteItem(new Inet6AddressGroup(addresses.getAddress().getAddress(), 128), addresses.getAddress().getAddress(),
this, "Direct", 0, 128, addresses.getMonitor(), "D",false);
rlist.add(ri);
RouteItem ris = new RouteItem(addresses.getLocator(), (Inet6Address) addresses.getLocator().getAddress(),
this, "KLALB SRv6", 13, 128, addresses.getMonitor(), "D",false);
rlist.add(ris);
}
return rlist;
}
}
+143 -3
View File
@@ -10,6 +10,8 @@ import java.net.UnknownHostException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.kne.cloud.network.MultipurposeSocketAddress;
@@ -135,8 +137,28 @@ public class KLALBUtils {
Color col=new Color( r,g,0);
return col;
}
public static Color getColorByLoadPercentagex(float f) {
int r=0;
int g=200;
if(f<50f) {
r+=f/50f*200f;
}else {
r=200;
g-=(f-50f)/50f*200f;
}
if(r>200)
r=200;
if(r<0)
r=0;
if(g>200)
g=200;
if(g<0)
g=0;
Color col=new Color( r,g,0);
return col;
}
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress)
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress, MultipurposeSocketAddress targetAddress,boolean buffered)
throws IOException {
if (targetAddress.isStream()) {
if (targetAddress.supportNIO()) {
@@ -164,14 +186,23 @@ public class KLALBUtils {
}
}
public static KLALBPacketLink createKLALBPacketLink(MultipurposeSocketAddress bindAddress,
MultipurposeSocketAddress targetAddress, int timeout) throws UnknownHostException, IOException {
MultipurposeSocketAddress targetAddress,boolean buffered, int timeout) throws UnknownHostException, IOException {
if (targetAddress.isStream()) {
if (targetAddress.supportNIO()) {
if (bindAddress != null) {
if(buffered) {
return new StreamChannelKLALBPacketLink(targetAddress
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
}else {
return new StreamChannelKLALBPacketLink(targetAddress
.connectSocketChannel(InetAddress.getByName(bindAddress.getHost()), bindAddress.getPort(),timeout));
}
} else {
if(buffered) {
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
}else {
return new StreamChannelKLALBPacketLink(targetAddress.connectSocketChannel(timeout));
}
}
} else {
if (bindAddress != null) {
@@ -190,7 +221,116 @@ public class KLALBUtils {
}
}
}
public static final String IPv6Reg = "([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$"
+ "|^:((:[\\da-fA-F]{1,4}){1,6}|:)$"
+ "|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$"
+ "|^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$"
+ "|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$"
+ "|^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$"
+ "|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$"
+ "|^([\\da-fA-F]{1,4}:){6}:"; // IPv6地址的格式
/**
* 将一个IPv6地址转为全写格式全写中的前导0省略
* 将1ade:03da:0::转为1ade:3da:0:0:0:0:0:0
*
* @param IPv6Str
* @return fullIPv6
*/
public static String parseFullIPv6(String IPv6Str) {
// 判断IPv6地址的格式是否正确
if (!IPv6Str.matches(IPv6Reg)) {
return "";
}
String[] arr = new String[]{"0", "0", "0", "0", "0", "0", "0", "0"};
// 将IPv6地址用::分开
// 如果IPv6地址为::tempArr.length==0
// 如果不包含::或以::结尾tempArr.length==1
// 如果以::开头或::在中间tempArr.length==2
String[] tempArr = IPv6Str.split("::");
// tempArr[0]:分开填充到arr前半部分
if (tempArr.length > 0) {
// new String[0]为空数组因为"".split(":"){""}如果tempArr[0]==""此时数组包含一个元素
String[] tempArr0 = tempArr[0].isEmpty() ? new String[0] : tempArr[0].split(":");
for (int i = 0; i < tempArr0.length; i++) {
// 如果是纯数字用parseInt去除前导0如果包含字母用正则去除前导0
arr[i] = tempArr0[i].matches("\\d+")
? (Integer.parseInt(tempArr0[i]) + "")
: tempArr0[i].replaceAll("^(0+)", "");
}
}
// tempArr[1]:分开填充到arr后半部分
if (tempArr.length > 1) {
String[] tempArr1 = tempArr[1].isEmpty() ? new String[0] : tempArr[1].split(":");
for (int i = 0; i < tempArr1.length; i++) {
arr[i + arr.length - tempArr1.length] = tempArr1[i].matches("\\d+")
? (Integer.parseInt(tempArr1[i]) + "")
: tempArr1[i].replaceAll("^(0+)", "");
}
}
return join(arr, ":");
}
private static String join(String[] arr, String string) {
StringBuilder sb=new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
if(i+1<arr.length) {
sb.append(string);
}
}
return sb.toString();
}
/**
* 将一个IPv6地址转为简写格式
* 将1ade:03da:0::转为1ade:3da::
*
* @param IPv6Str
* @return AbbrIPv6
*/
public static String parseAbbrIPv6(String IPv6Str) {
// 将一个IPv6地址转为全写格式全写中的前导0省略
String fullIPv6 = parseFullIPv6(IPv6Str);
if (fullIPv6.isEmpty()) { // 如果IPv6地址的格式不正确
return "";
}
// 将1ade:3da:0:0:0:0:0:99转为{"-","-","0","0","0","0","0","-"}
String[] arr = fullIPv6.split(":");
for (int i = 0, len = arr.length; i < len; i++) {
if (!"0".equals(arr[i])) {
arr[i] = "-";
}
}
// 找到最长的连续的0
Pattern pattern = Pattern.compile("0{2,}");
Matcher matcher = pattern.matcher(join(arr, ""));
String maxStr = "";
int start = -1;
int end = -1;
while (matcher.find()) {
if (maxStr.length() < matcher.group().length()) {
maxStr = matcher.group();
start = matcher.start();
end = matcher.end();
}
}
// 合并
arr = fullIPv6.split(":");
if (maxStr.length() > 0) {
for (int i = start; i < end; i++) {
arr[i] = ":";
}
}
return join(arr, ":").replaceAll(":{2,}", "::");
}
}
@@ -0,0 +1,24 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.SocketException;
import org.kne.cloud.network.RawSocket;
import org.kne.cloud.network.RawSocketImpl;
import org.kne.cloud.network.VirtualRawSocket;
import org.kne.cloud.network.srv6.SRv6Router;
public class KLALBVirtualRawSocket extends VirtualRawSocket {
public KLALBVirtualRawSocket(SRv6Router controller) {
super(new KLALBVirtualRawSocketImpl(controller));
}
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress) throws SocketException {
super(new KLALBVirtualRawSocketImpl(controller),bindAddress);
}
public KLALBVirtualRawSocket(SRv6Router controller,Inet6Address bindAddress,int bindProtocol) throws SocketException {
super(new KLALBVirtualRawSocketImpl(controller),bindAddress,bindProtocol);
}
}
@@ -0,0 +1,272 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
import org.kne.cloud.network.ByteBufferAllocator;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.RawSocketImpl;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.VirtualRawSocketImpl;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6Payload;
import org.kne.cloud.network.srv6.PacketConsumer;
import org.kne.cloud.network.srv6.SRv6Router;
import org.kne.concurrent.HighPerformanceExecutor;
import org.kne.io.KNEChannels;
public class KLALBVirtualRawSocketImpl extends VirtualRawSocketImpl implements PacketConsumer{
private boolean ipHeaderInclude=false;
private SRv6Router router;
protected volatile Inet6Address remoteaddr;
protected volatile Inet6Address localaddr;
private int bindProtocolNumber;
private volatile int inputchachesize = 1024*1024;
protected SRv6Router getRouter() {
return router;
}
public KLALBVirtualRawSocketImpl(SRv6Router router) {
super();
this.router = router;
}
@Override
public void setOption(int optID, Object value) throws SocketException {
// TODO 自动生成的方法存根
}
@Override
public Object getOption(int optID) throws SocketException {
// TODO 自动生成的方法存根
return null;
}
@Override
protected void create() throws IOException {
}
@Override
protected void setIPHeaderInclude(boolean ipHeaderInclude) throws IOException {
this.ipHeaderInclude=ipHeaderInclude;
}
@Override
protected boolean getIPHeaderInclude() throws IOException {
return ipHeaderInclude;
}
@Override
protected void setUseSelectTimeout(boolean useSelect) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected boolean getUseSelectTimeout() throws IOException {
// TODO 自动生成的方法存根
return false;
}
@Override
protected void setSendTimeout(int timeout) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected int getSendTimeout() throws IOException {
// TODO 自动生成的方法存根
return 0;
}
@Override
protected void setReceiveTimeout(int timeout) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected int getReceiveTimeout() throws IOException {
// TODO 自动生成的方法存根
return 0;
}
@Override
protected void close() {
router.getProtocolNumberRegister().remove(bindProtocolNumber);
}
@Override
protected void bind(InetAddress address,int protocolNumber) throws SocketException{
if(protocolNumber<0) {
throw new UnsupportedOperationException("unsupprted bind all protocols");
}
try {
if (address.equals(Inet4Address.getByName("0.0.0.0"))) {
address = Inet6Address.getByName("::0");
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
if (!(address instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
}
if ((!address.isAnyLocalAddress()) && (!address.equals(router.getLocator().getAddress()))) {
throw new BindException("must bind to self");
}
localaddr=(Inet6Address) address;
this.bindProtocolNumber=protocolNumber;
if(router.getProtocolNumberRegister().putIfAbsent(protocolNumber, this)!=null) {
throw new BindException("protocol number already bind");
}
}
@Override
protected void join(InetAddress inetaddr) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void leave(InetAddress inetaddr) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void joinGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void leaveGroup(InetAddress mcastaddr, NetworkInterface netIf) throws IOException {
// TODO 自动生成的方法存根
}
@Override
protected void send(DatagramPacket p) throws IOException {
ByteBuffer buf= ByteBuffer.wrap(p.getData(), p.getOffset(), p.getLength());
if(ipHeaderInclude) {
}else {
HighPerformanceExecutor.defaultExecutor.execute(() -> {
IPv6Packet ipv=new IPv6Packet();
ipv.setVersion(6);
ipv.setTrafficClass(0);
ipv.setFlowLabel(0);
ipv.setHopLimit(255);
ipv.setSourceAddress(router.getLocator().getAddress());
InetAddress address= p.getAddress();
if (!(address instanceof Inet6Address)) {
throw new IllegalArgumentException("invalid address type, KLALB socket can only use IPV6 address");
}
ipv.setDestinationAddress((Inet6Address)address);
ipv.setPriority(3);
//ipv.enableECN();
IPv6Payload pl=new IPv6Payload(bindProtocolNumber);
pl.getData().put(buf);
pl.getData().flip();
ipv.setPayload(pl);
router.insertSRHandRoutePacket(ipv);
});
}
}
@Override
protected InetAddress peek() throws IOException {
return peekNextPacket().getSourceAddress();
}
@Override
protected void peekData(DatagramPacket p) throws IOException {
IPv6Packet pack=peekNextPacket();
copyTo(pack, p);
}
private void copyTo(IPv6Packet pack, DatagramPacket p) throws IOException {
p.setAddress(pack.getSourceAddress());
ByteBuffer buffer= ByteBuffer.wrap(p.getData(),p.getOffset(),p.getLength());
if(ipHeaderInclude) {
}else {
try {
pack.getPayload().writeToChannel(KNEChannels.newWritableChannel(buffer));
}catch(BufferOverflowException e) {
}
}
buffer.flip();
p.setLength(buffer.limit());
}
@Override
protected void receive(DatagramPacket p) throws IOException {
IPv6Packet pack=pollNextPacket();
copyTo(pack, p);
}
private volatile Thread parkThread;
private IPv6Packet peekNextPacket() {
IPv6Packet pol=null;
while(true) {
pol=recvQueue.peek();
if(pol!=null) {
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
return pol;
}
parkThread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
}
}
private IPv6Packet pollNextPacket() {
IPv6Packet pol=null;
while(true) {
pol=recvQueue.poll();
if(pol!=null) {
recvQueueUsed.addAndGet((int) -pol.getPayload().getLength());
return pol;
}
parkThread=Thread.currentThread();
LockSupport.parkNanos(1000000L);
}
}
private Queue<IPv6Packet> recvQueue = new ConcurrentLinkedQueue<IPv6Packet>();
private AtomicInteger recvQueueUsed=new AtomicInteger(0);
@Override
public void accept(IPv6Packet packx) throws IOException {
if(recvQueueUsed.get()<=inputchachesize) {
if(recvQueue.offer(packx)) {
recvQueueUsed.addAndGet((int) packx.getPayload().getLength());
LockSupport.unpark(parkThread);
}
}
}
}
@@ -14,16 +14,16 @@ public class KLALBVirtualSocket extends VirtualSocket {
return (KLALBVirtualSocketImpl) super.getVirtualImpl();
}
private KLALBController controler;
private KLALBController controller;
protected SocketChannel channel;
public KLALBVirtualSocket(KLALBController controler) throws SocketException {
super(controler.createVirtualImpl());
this.controler = controler;
this.controller = controler;
}
protected KLALBController getControler() {
return controler;
protected KLALBController getController() {
return controller;
}
public KLALBVirtualSocket(KLALBController controler,String host, int port) throws UnknownHostException, IOException {
@@ -115,8 +115,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
@Override
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
// TODO 自动生成的方法存根
return 0;
return ((KVSIInputStream)socket.getInputStream()).read(dsts,offset,length);
}
@Override
@@ -126,8 +125,7 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
@Override
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
// TODO 自动生成的方法存根
return 0;
return ((KVSIOutputStream)socket.getOutputStream()).write(srcs,offset,length);
}
@Override
@@ -151,4 +149,10 @@ public class KLALBVirtualSocketChannel extends SocketChannel{
socket.associateSocketChannel(b);
}
public boolean isAutoFlush() throws IOException {
return ((KVSIOutputStream)socket.getOutputStream()).isAutoFlush();
}
public void setAutoFlush(boolean b) throws IOException {
((KVSIOutputStream)socket.getOutputStream()).setAutoFlush(b);
}
}
File diff suppressed because it is too large Load Diff
@@ -34,11 +34,11 @@ public class PortBinder {
this.controller = controller;
}
private ReentrantReadWriteLock bindMaplock=new ReentrantReadWriteLock();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>bindMap=new ConcurrentHashMap<>(65536*16);
private ReentrantReadWriteLock listenMaplock=new ReentrantReadWriteLock();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>();
private Map<InetSocketAddress,BindableKLALBPacketConsumer>listenMap=new ConcurrentHashMap<>(65536*16);
private ReentrantReadWriteLock connectMaplock=new ReentrantReadWriteLock();
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>();
private Map<Pair<InetSocketAddress,InetSocketAddress>,BindableKLALBPacketConsumer>connectMap=new ConcurrentHashMap<>(65536*16);
private volatile int portn=65535;
public void bind(BindableKLALBPacketConsumer ks) throws BindException {
bindMaplock.writeLock().lock();
@@ -205,7 +205,7 @@ public class PortBinder {
return b;
}*/
public boolean distributePacketToConsumer(Inet6Address srcAddr,PortPacket packet) {
InetSocketAddress local=new InetSocketAddress(controller.getSelf(), packet.getDport());
InetSocketAddress local=new InetSocketAddress(controller.getSelf().getAddress(), packet.getDport());
InetSocketAddress remote=new InetSocketAddress(srcAddr, packet.getSport());
BindableKLALBPacketConsumer bkc=connectMap.get(new Pair<InetSocketAddress, InetSocketAddress>(local, remote));
if(bkc!=null) {
@@ -0,0 +1,22 @@
package org.kne.cloud.network.klalb;
import org.kne.cloud.network.ipv6.IPv6Packet;
public class SendItem {
private IPv6Packet packet;
private long sendtime=System.nanoTime();
public SendItem(IPv6Packet packet) {
this.packet=packet;
}
public IPv6Packet getPacket() {
return packet;
}
public long getSendtime() {
return sendtime;
}
}
@@ -129,18 +129,20 @@ import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.DatagramServerSocket;
import org.kne.cloud.network.DatagramServerSocket.SubDatagramSocket;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.PacketRebuilder;
import org.kne.cloud.network.PacketSpliter;
import org.kne.cloud.network.SpeedLimiter;
import org.kne.debug.TimeDebugger;
public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
private PacketSpliter pslr=new PacketSpliter(65535);
private PacketRebuilder pbdr=new PacketRebuilder(1000000000);
public class SplitedDatagramKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
private PacketSpliter pslr;
private PacketRebuilder pbdr;
@Override
public String toString() {
@@ -151,13 +153,60 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
public SplitedDatagramKLALBPacketLink(DatagramSocket connectDatagramSocket) throws IOException {
this.ds=connectDatagramSocket;
bibf.limit(0);
pslr=new PacketSpliter(new WritableByteChannel() {
@Override
public boolean isOpen() {
return !ds.isClosed();
}
@Override
public void close() throws IOException {
}
@Override
public int write(ByteBuffer src) throws IOException {
int rem=src.remaining();
byte[]bt=src.array();
DatagramPacket dp=new DatagramPacket(bt,src.position(),src.limit());
//System.out.println("SendDatagram:"+src.remaining());
ds.send(dp);
return rem;
}
},1350);
pbdr=new PacketRebuilder(new ReadableByteChannel() {
@Override
public boolean isOpen() {
return !ds.isClosed();
}
@Override
public void close() throws IOException {
}
@Override
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
if(ds instanceof SubDatagramSocket) {
dp=((SubDatagramSocket) ds).receive();
dst.put(dp.getData(), 0, dp.getLength());
}else {
dp=new DatagramPacket(bc, bc.length);
ds.receive(dp);
dst.put(dp.getData(), 0, dp.getLength());
}
//System.out.println("RecvDatagram:"+dp.getLength());
return dp.getLength();
}
},1000000000);
}
private ByteBuffer bbf=ByteBuffer.allocate(65535);
//private ByteBuffer bbf=ByteBuffer.allocate(65535);
@Override
public void writePacket(KLALBPacket kp) throws IOException {
/*@Override
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
//System.out.println(" TX:"+kp);
//KLALBPacket.writeKLALBPacketToStream(dos, kp);
KLALBPacket.writeKLALBPacketToChannel(new WritableByteChannel() {
@@ -184,47 +233,21 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
}
}, kp);
}
}*/
private byte[]bc=new byte[65535];
private ByteBuffer bibf=ByteBuffer.allocate(65535);
//private ByteBuffer bibf=ByteBuffer.allocate(65535);
@Override
public KLALBPacket readPacket() throws IOException {
/*@Override
public KLALBPacket readKLALBPacket() throws IOException {
KLALBPacket kp=null;
do {
if(bibf.remaining()<=0) {
bibf.clear();
/*DatagramPacket dp=new DatagramPacket(bc, bc.length);
ds.receive(dp);
bibf.put(dp.getData(), 0, dp.getLength());*/
pbdr.read(bibf,new ReadableByteChannel() {
@Override
public boolean isOpen() {
return true;
}
@Override
public void close() throws IOException {
}
@Override
public int read(ByteBuffer dst) throws IOException {DatagramPacket dp;
if(ds instanceof SubDatagramSocket) {
dp=((SubDatagramSocket) ds).receive();
dst.put(dp.getData(), 0, dp.getLength());
}else {
dp=new DatagramPacket(bc, bc.length);
ds.receive(dp);
dst.put(dp.getData(), 0, dp.getLength());
}
return dp.getLength();
}
} );
pbdr.read(bibf );
bibf.flip();
}
@@ -259,7 +282,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
}while(true);
return kp;
}
*/
@Override
public void close() throws IOException {
ds.close();
@@ -280,7 +303,7 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
return ds.getSoTimeout();
}
@Override
/*@Override
public void flush() throws IOException {
bbf.flip();
//TimeDebugger tdb=new TimeDebugger();
@@ -307,16 +330,34 @@ public class SplitedDatagramKLALBPacketLink implements KLALBPacketLink {
});
//tdb.putTime("flushEnd");
//tdb.print();
/*byte[]bt=bbf.array();
DatagramPacket dp=new DatagramPacket(bt,bbf.limit());
ds.send(dp);*/
bbf.clear();
}
}*/
@Override
public boolean isStream() {
return false;
}
@Override
public void writePacket(ByteBuffer kp) throws IOException {
incOutput(kp.remaining());
pslr.write(kp);
}
@Override
public ByteBuffer readPacket() throws IOException {
ByteBuffer bbf=NetworkPacket.bufferAllocator.allocate(65535);
pbdr.read(bbf );
bbf.flip();
incInput(bbf.remaining());
return bbf;
}
@Override
public void flush() throws IOException {
// TODO 自动生成的方法存根
}
}
@@ -1,6 +1,7 @@
package org.kne.cloud.network.klalb;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
@@ -19,14 +20,19 @@ import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.ByteBufferAllocator;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.TimeoutTimer;
import org.kne.io.KNEChannels;
public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
public class StreamChannelKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
private volatile long timeoutTimer;
private volatile boolean timerenabled=false;
private Thread timeouter=new Thread() {
private Runnable timeouter=new Runnable() {
public void run() {
timeoutTimer=System.nanoTime();
while(connectSocket.isOpen()) {
@@ -38,7 +44,7 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
}
}
try {
Thread.sleep(1);
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -59,29 +65,13 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
public StreamChannelKLALBPacketLink(SocketChannel connectSocket) throws IOException {
this.connectSocket=connectSocket;
connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
timeouter.start();
ThreadTool.makeVDaemonThread("连接超时计时线程", timeouter);
new KLALBOutputStream(Channels.newOutputStream(connectSocket));
new KLALBInputStream(Channels.newInputStream(connectSocket));
}
@Override
public void writePacket(KLALBPacket kp) throws IOException {
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
}
@Override
public KLALBPacket readPacket() throws IOException {
timeoutTimer=System.nanoTime();
timerenabled=true;
KLALBPacket res;
try {
res=KLALBPacket.readKLALBPacketFromChannel(connectSocket);
}finally {
timerenabled=false;
}
return res;
}
@Override
public void close() throws IOException {
@@ -113,5 +103,136 @@ public class StreamChannelKLALBPacketLink implements KLALBPacketLink {
public boolean isStream() {
return true;
}
@Override
public void writePacket(ByteBuffer kp) throws IOException {
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
szeWrite.limit(4);
//szeWrite.clear();
incOutput(kp.limit());
szeWrite.putInt(kp.limit());
szeWrite.flip();
KLALBVirtualSocketChannel obj = null;
connectSocket.write(new ByteBuffer[] {szeWrite,kp});
/*
if(connectSocket instanceof KLALBVirtualSocketChannel) {
obj=(KLALBVirtualSocketChannel) connectSocket;
}
boolean isaflush=false;
if(obj!=null) {
isaflush=obj.isAutoFlush();
obj.setAutoFlush(false);
}
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,false);
connectSocket.write(szeWrite);
//connectSocket.setOption(StandardSocketOptions.TCP_NODELAY,true);
if(obj!=null) {
obj.setAutoFlush(true);
}
connectSocket.write(kp);
if(obj!=null) {
obj.setAutoFlush(isaflush);
}*/
}
@Override
public void writePackets(ByteBuffer[] kpp,int off,int len) throws IOException {
ByteBuffer[] bbfw=new ByteBuffer[len<<1];
for(int i=0;i<len;i++) {
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
szeWrite.limit(4);
//szeWrite.clear();
incOutput(kpp[off+i].limit());
szeWrite.putInt(kpp[off+i].limit());
szeWrite.flip();
KLALBVirtualSocketChannel obj = null;
bbfw[i*2]=szeWrite;
bbfw[i*2+1]=kpp[i];
}
connectSocket.write(bbfw);
}
@Override
public ByteBuffer readPacket() throws IOException {
timeoutTimer=System.nanoTime();
timerenabled=true;
ByteBuffer kp;
ByteBuffer szeRead=NetworkPacket.bufferAllocator.allocate(4);
szeRead.limit(4);
//szeRead.clear();
try {
KNEChannels.readFully(connectSocket,szeRead);
szeRead.flip();
int size=szeRead.getInt(0);
kp=NetworkPacket.bufferAllocator.allocate(size);
incInput(size);
kp.limit(size);
KNEChannels.readFully(connectSocket, kp);
kp.flip();
return kp;
}finally {
timerenabled=false;
}
}
/* @Override
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
szeWrite.limit(4);
//szeWrite.clear();
int length=(int) kp.getLength();
incOutput(length);
szeWrite.putInt(length);
szeWrite.flip();
KLALBVirtualSocketChannel obj = null;
if(connectSocket instanceof KLALBVirtualSocketChannel) {
obj=(KLALBVirtualSocketChannel) connectSocket;
}
boolean isaflush=false;
if(obj!=null) {
isaflush=obj.isAutoFlush();
obj.setAutoFlush(false);
}
connectSocket.write(szeWrite);
if(obj!=null) {
obj.setAutoFlush(true);
}
KLALBPacket.writeKLALBPacketToChannel(connectSocket, kp);
if(obj!=null) {
obj.setAutoFlush(isaflush);
}
}
@Override
public KLALBPacket readKLALBPacket() throws IOException {
ByteBuffer szeWrite=NetworkPacket.bufferAllocator.allocate(4);
szeWrite.limit(4);
KNEChannels.readFully(connectSocket, szeWrite);
szeWrite.flip();
int readSize=szeWrite.getInt();
incInput(readSize);
return KLALBPacket.readKLALBPacketFromChannel(connectSocket);
}*/
}
@@ -7,10 +7,11 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import org.kne.cloud.network.MultipurposeSocketAddress;
public class StreamKLALBPacketLink implements KLALBPacketLink {
public class StreamKLALBPacketLink extends AbstractKLALBPacketLink implements KLALBPacketLink {
@Override
public String toString() {
@@ -30,13 +31,13 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
}
@Override
public void writePacket(KLALBPacket kp) throws IOException {
out.writePacket(kp);
public void writeKLALBPacket(KLALBPacket kp) throws IOException {
out.writeKLALBPacket(kp);
}
@Override
public KLALBPacket readPacket() throws IOException {
return in.readPacket();
public KLALBPacket readKLALBPacket() throws IOException {
return in.readKLALBPacket();
}
@Override
@@ -68,5 +69,15 @@ public class StreamKLALBPacketLink implements KLALBPacketLink {
public boolean isStream() {
return true;
}
@Override
public void writePacket(ByteBuffer kp) throws IOException {
out.writePacket(kp);
}
@Override
public ByteBuffer readPacket() throws IOException {
return in.readPacket();
}
}
@@ -0,0 +1,512 @@
package org.kne.cloud.network.klalb.ui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.net.Inet6Address;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.JPanel;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
public class GraphPanel extends JPanel {
private Map<Inet6Address,GraphNode> nodes=new ConcurrentHashMap<Inet6Address,GraphNode>();
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
public Map<Inet6Address, GraphNode> getNodes() {
return nodes;
}
public List<GraphEdgeGroup> getEdgeGroups() {
return edgeGroups;
}
private double borderGap=250;
private double translateX,translateY;
private double scale=1;
public double getTranslateX() {
return translateX;
}
public double getTranslateY() {
return translateY;
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d=(Graphics2D)g;
recalcTranslate();
g2d.scale(scale, scale);
g2d.translate(translateX,translateY);
double w=xmax-xmin;
double h=ymax-ymin;
if(w>=0&&h>=0) {
g2d.drawRect((int)(xmin-borderGap), (int)(ymin-borderGap), (int)(w+borderGap*2), (int)(h+borderGap*2));
}
synchronized (edgeGroups) {
for( GraphEdgeGroup graphNode :edgeGroups) {
graphNode.paint(g2d);
}
}
for(GraphNode graphNode :nodes.values()) {
graphNode.paint(g2d);
}
}
public class GraphNode{
private String text;
private Color color;
private double nodesize=40;
private double x;
private double y;
private boolean ismarked;
private Vector2 delta=new Vector2(0, 0);
public GraphNode(String text, Color color, double x, double y,boolean ismarked) {
super();
this.text = text;
this.color = color;
this.x = x;
this.y = y;
this.ismarked=ismarked;
}
public double getNodesize() {
return nodesize;
}
public void setNodesize(double nodesize) {
this.nodesize = nodesize;
}
public boolean isIsmarked() {
return ismarked;
}
public void setIsmarked(boolean ismarked) {
this.ismarked = ismarked;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public double getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public GraphNode() {
super();
}
public double getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void paint(Graphics2D g) {
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(2.0f));
g.drawOval((int)(x-nodesize/2), (int)(y-nodesize/2), (int)(nodesize), (int)(nodesize));
g.setFont(UIEnv.getFont().deriveFont(10.0f));
g.drawString(text, (int)(x+nodesize/2), (int)(y-nodesize/3));
if(ismarked) {
Vector2 pos=new Vector2(x, y);
Vector2 v2a=new Vector2(0, -1).multi(nodesize/4);
Vector2 v2b=new Vector2(Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
Vector2 v2c=new Vector2(-Math.sqrt(3)/2.0, 0.5).multi(nodesize/4);
v2a=v2a.add(pos);
v2b=v2b.add(pos);
v2c=v2c.add(pos);
g.drawPolygon(new int[] {(int) v2a.x,(int) v2b.x,(int) v2c.x}, new int[] {(int) v2a.y,(int) v2b.y,(int) v2c.y}, 3);
}
}
public Vector2 getPositionVec2() {
return new Vector2(x, y);
}
public void commitDelta() {
x+=delta.x;
y+=delta.y;
delta=new Vector2(0, 0);
}
public void clearDelta() {
delta=new Vector2(0, 0);
}
}
public class GraphEdge{
private GraphNode from;
private GraphNode to;
LinkDirection linkPath;
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
this.from=nfrom;
this.to=nto;
this.linkPath=lp;
}
}
public class GraphEdgeGroup{
private double length=100;
private double gap=12;
private boolean isShortest=false;
private GraphNode nodeA,nodeB;
private List<GraphEdge> edges=new ArrayList<>();
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getGap() {
return gap;
}
public void setGap(double gap) {
this.gap = gap;
}
public boolean match(GraphNode a,GraphNode b) {
if(a.equals( nodeA)&&b.equals( nodeB))
return true;
if(b.equals( nodeA)&&a.equals( nodeB))
return true;
return false;
}
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
super();
this.nodeA = nodeA;
this.nodeB = nodeB;
}
public boolean isShortest() {
return isShortest;
}
public void setShortest(boolean isShortest) {
this.isShortest = isShortest;
}
public List<GraphEdge> getPaths() {
return getEdges();
}
public void paint(Graphics2D g) {
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
Vector2 vecDir=nodeBv.subtract(nodeAv);
Vector2 vecDirnor=vecDir.normalize();
Vector2 vecRA=vecDirnor.multi(nodeA.getNodesize()/2);
Vector2 vecRB=vecDirnor.multi(nodeB.getNodesize()/2);
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
//所有线路完整显示
/*
double width=gap*(edges.size()-1);
//System.out.println(width);
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
GraphEdge graphEdge = (GraphEdge) iterator.next();
//System.out.println(vec90nor);
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
startPoint=startPoint.subtract(vec90nor.multi(gap));
endPoint=endPoint.subtract(vec90nor.multi(gap));
}
*/
long totalupspeed=0;
long usedupspeed=0;
long totaldownspeed=0;
long useddownspeed=0;
for(GraphEdge graphEdge :getEdges()) {
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) ) {
totalupspeed+=graphEdge.linkPath.getBandwidth();
usedupspeed+=graphEdge.linkPath.getSpeed();
}
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) ) {
totaldownspeed+=graphEdge.linkPath.getBandwidth();
useddownspeed+=graphEdge.linkPath.getSpeed();
}
}
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totalupspeed/10.0/1024.0))));
double width=gap*1;
Vector2 startPoint=nodeAv.add(vecRA).add(vec90nor.multi(width/2));
Vector2 endPoint=nodeBv.subtract(vecRB).add(vec90nor.multi(width/2));
g.setColor(KLALBUtils.getColorByLoadPercentagex(usedupspeed*100f/totalupspeed));
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
startPoint=startPoint.subtract(vec90nor.multi(gap));
endPoint=endPoint.subtract(vec90nor.multi(gap));
g.setStroke(new BasicStroke((float) Math.max(2.0, Math.log10(totaldownspeed/10.0/1024.0))));
g.setColor(KLALBUtils.getColorByLoadPercentagex(useddownspeed*100f/totaldownspeed));
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
startPoint=startPoint.subtract(vec90nor.multi(gap));
endPoint=endPoint.subtract(vec90nor.multi(gap));
if(isShortest) {
BasicStroke dotted = new BasicStroke(2, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0, new float[]{0,3,0,3}, 0);
g.setStroke(dotted);
g.setColor(Color.BLUE);
g.drawLine((int)nodeA.getX(), (int)nodeA.getY(), (int)nodeB.getX(), (int)nodeB.getY());
}
}
public List<GraphEdge> getEdges() {
return edges;
}
}
// 计算
public static double[] rotateVec(int px, int py, double ang,
boolean isChLen, double newLen) {
double mathstr[] = new double[2];
// 矢量旋转函数参数含义分别是x分量y分量旋转角是否改变长度新长度
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
{
double H = 13; // 箭头高度
double L = 8; // 底边的一半
int x3 = 0;
int y3 = 0;
int x4 = 0;
int y4 = 0;
double awrad = Math.atan(L / H); // 箭头角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
double y_3 = ey - arrXY_1[1];
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
double y_4 = ey - arrXY_2[1];
Double X3 = new Double(x_3);
x3 = X3.intValue();
Double Y3 = new Double(y_3);
y3 = Y3.intValue();
Double X4 = new Double(x_4);
x4 = X4.intValue();
Double Y4 = new Double(y_4);
y4 = Y4.intValue();
// 画线
g2.drawLine(sx, sy, ex, ey);
//
GeneralPath triangle = new GeneralPath();
triangle.moveTo(ex, ey);
triangle.lineTo(x3, y3);
triangle.lineTo(x4, y4);
triangle.closePath();
//实心箭头
g2.fill(triangle);
//非实心箭头
//g2.draw(triangle);
}
protected void loadNodes() {
updateBounds();
}
private void recalcTranslate() {
double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
for(GraphNode graphNode:nodes.values()) {
xmin=Math.min(xmin, graphNode.x);
xmax=Math.max(xmax, graphNode.x);
ymin=Math.min(ymin, graphNode.y);
ymax=Math.max(ymax, graphNode.y);
}
this.xmin=xmin;
this.xmax=xmax;
this.ymin=ymin;
this.ymax=ymax;
if(xmin!=Double.MAX_VALUE) {
translateX=-xmin+borderGap;
translateY= -ymin+borderGap;
}
}
private double xmin=Double.MAX_VALUE,xmax=Double.MIN_VALUE;
private double ymin=Double.MAX_VALUE,ymax=Double.MIN_VALUE;
public void updateBounds() {
recalcTranslate();
if(xmin!=Double.MAX_VALUE) {
Dimension d=new Dimension((int)(((xmax-xmin)+borderGap*2)*scale),(int)(((ymax-ymin)+borderGap*2)*scale) );
setPreferredSize(d);
setSize(d);
}
}
public void runPhy() {
for( GraphNode graphEdgeGroup :nodes.values()) {
Vector2 vecpos=graphEdgeGroup.getPositionVec2();
Vector2 vec=new Vector2(0, 0);
for (Iterator<GraphNode> iteratorx =nodes.values().iterator(); iteratorx.hasNext();) {
GraphNode graphEdgeGroup2 = (GraphNode) iteratorx.next();
if(graphEdgeGroup2!=graphEdgeGroup) {
Vector2 vecpos2=graphEdgeGroup2.getPositionVec2();
Vector2 sub=vecpos.subtract(vecpos2);
double distance=sub.Length();
Vector2 dic=sub.normalize();
vec=vec.add(dic.multi(Math.min(10.0/distance,10.0)));
}
}
graphEdgeGroup.delta=graphEdgeGroup.delta.add(vec);
}
synchronized (edgeGroups) {
for(GraphEdgeGroup graphEdgeGroup :edgeGroups) {
GraphNode na=graphEdgeGroup.nodeA;
GraphNode nb=graphEdgeGroup.nodeB;
Vector2 veca=na.getPositionVec2();
Vector2 vecb=nb.getPositionVec2();
Vector2 sub=veca.subtract(vecb);
double distance=sub.Length();
double length=graphEdgeGroup.getLength()+na.getNodesize()/2+nb.getNodesize()/2;
//System.out.println(length);
if(distance>length) {
Vector2 dicb=sub.normalize().multi((distance-length)/3);
Vector2 dica=dicb.opposite();
na.delta=na.delta.add(dica);
nb.delta=nb.delta.add(dicb);
}
}
}
for( GraphNode graphEdgeGroup:nodes.values()) {
graphEdgeGroup.commitDelta();
}
}
private Random r=new Random();
public Vector2 getRandomPos() {
double x,y;
if(xmin>=xmax) {
x=r.nextDouble();
}else {
x=r.nextDouble(xmin, xmax);
}
if(ymin>=ymax) {
y=r.nextDouble();
}else {
y=r.nextDouble(ymin, ymax);
}
return new Vector2(x, y);
}
}
@@ -5,9 +5,12 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.MenuItem;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.Rectangle;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
@@ -18,7 +21,14 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
@@ -32,7 +42,9 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import org.jfree.chart.ChartPanel;
@@ -45,11 +57,14 @@ import org.jfree.chart.plot.dial.StandardDialRange;
import org.jfree.chart.plot.dial.StandardDialScale;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.data.general.DefaultValueDataset;
import org.kne.cloud.klalb.uitool.SettingItem;
import org.kne.cloud.klalb.uitool.TextSettingItem;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.klalb.ui.GraphPanel.GraphNode;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane;
@@ -63,8 +78,6 @@ public class KLALBStateGUI2 extends XFrame {
private TrayIcon ti;
private long rate=200;
private Timer t,t2,t3;
private JCheckBoxMenuItem showoffline;
@@ -103,13 +116,16 @@ public class KLALBStateGUI2 extends XFrame {
private DefaultValueDataset downEfficiency;*/
private YScrollPane ysp;
private YScrollPane ysp,yspc;
private JTextField devicesOnline;
private JTextField textField;
private JTextField addressField;
private JTextField addressField2;
private JTextField asnField;
private NetworkGraphPanel graph;
private JTextField textFieldLocate;
/**
@@ -771,11 +787,135 @@ public class KLALBStateGUI2 extends XFrame {
JPanel panel_4 = new JPanel();
panel_3.add(panel_4, BorderLayout.NORTH);
panel_4.setLayout(new BorderLayout(0, 0));
textFieldLocate = new JTextField();
panel_4.add(textFieldLocate, BorderLayout.CENTER);
textFieldLocate.setColumns(10);
graph = new NetworkGraphPanel(kc.getIpv6Router().getKlalbRouteProtol());
graph.setOpaque(false);
JScrollPane jsp=new JScrollPane(graph);
JScrollPane jsp=new JScrollPane();jsp.setWheelScrollingEnabled(false);
jsp.setViewportView(graph);
MouseAdapter ma = new MouseAdapter() {
private Point origin;
@Override
public void mousePressed(MouseEvent e) {
origin = new Point(e.getPoint());
//System.out.println(e);
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
if (origin != null) {
//System.out.println(e);
//JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, jsp);
//if (viewPort != null) {
int deltaX = origin.x - e.getX();
int deltaY = origin.y - e.getY();
Rectangle view = jsp.getViewport().getVisibleRect();
view.x += deltaX;
view.y += deltaY;
jsp.getViewport().scrollRectToVisible(view);
// }
}
}
};
graph.addMouseWheelListener(new MouseWheelListener() {
private double scaleidx=1;
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
int val= e.getWheelRotation();
double scaleidxold=scaleidx;
scaleidx*=Math.pow(1.1, val);
if(scaleidx>5) {
scaleidx=5;
}
if(scaleidx<0.1) {
scaleidx=0.1;
}
double pow=scaleidx/scaleidxold;
Point pos = jsp.getViewport().getViewPosition();
double canvasX=e.getX();
double canvasY=e.getY();
double w=graph.getWidth();
double h=graph.getHeight();
double percentX=canvasX/w;
double percentY=canvasY/h;
graph.setScale(scaleidx);
graph.updateBounds();
double newcanvasX=percentX*w*pow;
double newcanvasY=percentY*h*pow;
double dx= newcanvasX-canvasX;
double dy=newcanvasY-canvasY;
//System.out.println(dx+" "+dy);
pos.x+=dx;
pos.y+=dy ;
jsp.getViewport().setViewPosition(pos);
}
});
JButton btnLocate = new JButton("Locate");
btnLocate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text= textFieldLocate.getText();
try {
Inet6Address addr=(Inet6Address) Inet6Address.getByName(text);
GraphNode node= graph.getNodes().get(addr);
if(node==null) {
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Address not found", "Warning", JOptionPane.WARNING_MESSAGE);
}else {
Point pos = new Point();
graph.updateBounds();
Dimension dim= jsp.getViewport().getExtentSize();
// System.out.println(dim);
pos.x =(int) ((node.getX()+graph.getTranslateX())*graph.getScale()-dim.width/2);
pos.y =(int) ((node.getY()+graph.getTranslateY())*graph.getScale()-dim.height/2);
jsp.getViewport().setViewPosition(pos);
}
} catch (UnknownHostException e1) {
JOptionPane.showMessageDialog(KLALBStateGUI2.this, "Input format error", "Error", JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
}
}
});
panel_4.add(btnLocate, BorderLayout.EAST);
JButton btnHome = new JButton("Home");
btnHome.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textFieldLocate.setText(addressField.getText());
btnLocate.doClick();
}
});
panel_4.add(btnHome, BorderLayout.WEST);
graph.addMouseListener(ma);
graph.addMouseMotionListener(ma);
panel_3.add(jsp, BorderLayout.CENTER);
yspc = new YScrollPane(730);
yspc.setOpaque(false);
JPanel configsPanel = new JPanel();
configsPanel.setLayout(new BorderLayout(0, 0));
configsPanel.add(yspc);
addSettingItems(yspc);
JButton btnSave = new JButton("Save settings");
yspc.add(btnSave, BorderLayout.NORTH);
tabbedPane.addTab("Settings", null, configsPanel, null);
configsPanel.setOpaque(false);
textField.addKeyListener(new KeyListener() {
@Override
@@ -795,7 +935,43 @@ public class KLALBStateGUI2 extends XFrame {
}
}
});
textFieldLocate.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
if(e.getKeyCode()==KeyEvent.VK_ENTER) {
btnLocate.doClick();
}
}
});
}
private void addSettingItems(YScrollPane settings) {
SettingItem si=new SettingItem("Basic settings",UIEnv.getFont().deriveFont(20.0f).deriveFont(Font.BOLD),CONST.itemwidth,CONST.settingheight);
settings.getView().add(si);
TextSettingItem addr6=new TextSettingItem("IPv6 address",CONST.itemwidth,CONST.settingheight);
addressField2=addr6.getTextField();
settings.getView().add(addr6);
TextSettingItem asn=new TextSettingItem("AS number",CONST.itemwidth,CONST.settingheight);
asnField=asn.getTextField();
settings.getView().add(asn);
settings.updateScrool();
}
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
if(tsk!=null) {
tsk.cancel();
@@ -920,13 +1096,22 @@ public class KLALBStateGUI2 extends XFrame {
if(!contt.equals(devicesOnline.getText())) {
devicesOnline.setText(contt);
}
String address=kc.getSelf().getHostAddress();
String address=kc.getSelf().getAddress().getHostAddress();
if(!address.equals(addressField.getText())) {
addressField.setText(address);
}
if(!address.equals(addressField2.getText())) {
addressField2.setText(address);
}
String asnstr=Long.toString( kc.getIpv6Router().getASN());
if(!asnstr.equals(asnField.getText())) {
asnField.setText(asnstr);
}
}
};
t2.scheduleAtFixedRate(tsk2, 200, 50);
t2.scheduleAtFixedRate(tsk2, 200, 100);
if(tsk3!=null) {
tsk3.cancel();
@@ -970,7 +1155,7 @@ public class KLALBStateGUI2 extends XFrame {
}
}
};
t3.scheduleAtFixedRate(tsk4, 200, 10);
t3.scheduleAtFixedRate(tsk4, 200, 20);
if(tsk5!=null) {
tsk5.cancel();
}
@@ -978,11 +1163,15 @@ public class KLALBStateGUI2 extends XFrame {
@Override
public void run() {
if(graph.isVisible())
graph.loadNodes();
graph.runPhy();
if(graph.isVisible()) {
graph.repaint();
graph.revalidate();
}
}
};
t.scheduleAtFixedRate(tsk5, 200, 2000);
t.scheduleAtFixedRate(tsk5, 200, 100);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@@ -2,6 +2,7 @@ package org.kne.cloud.network.klalb.ui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
@@ -14,6 +15,7 @@ import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.image.ImageObserver;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
@@ -26,240 +28,80 @@ import java.util.Set;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol;
import org.kne.cloud.network.srv6.KLALBRoutingProtocol.LinkDirection;
public class NetworkGraphPanel extends JPanel {
public class NetworkGraphPanel extends GraphPanel {
private KLALBRoutingProtocol routingProtocol;
private Map<Inet6Address,GraphNode> nodes=new HashMap<Inet6Address,GraphNode>();
private List<GraphEdgeGroup> edgeGroups=new ArrayList<GraphEdgeGroup>();
private static final int nodesize=80;
private class GraphNode{
private String text;
private Color color;
private int x;
private int y;
public GraphNode(String text, Color color, int x, int y) {
super();
this.text = text;
this.color = color;
this.x = x;
this.y = y;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public GraphNode() {
super();
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void paint(Graphics2D g) {
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(2.0f));
g.drawOval(x-nodesize/2, y-nodesize/2, nodesize, nodesize);
g.setFont(UIEnv.getFont().deriveFont(10.0f));
g.drawString(text, x+nodesize/2, y-nodesize/3);
}
}
private class GraphEdge{
private GraphNode from;
private GraphNode to;
private LinkDirection linkPath;
public GraphEdge(GraphNode nfrom, GraphNode nto,LinkDirection lp) {
this.from=nfrom;
this.to=nto;
this.linkPath=lp;
}
}
private class GraphEdgeGroup{
private static final double gap=3;
private GraphNode nodeA,nodeB;
private List<GraphEdge> edges=new ArrayList<>();
private boolean match(GraphNode a,GraphNode b) {
if(a.equals( nodeA)&&b.equals( nodeB))
return true;
if(b.equals( nodeA)&&a.equals( nodeB))
return true;
return false;
}
public GraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
super();
this.nodeA = nodeA;
this.nodeB = nodeB;
}
public List<GraphEdge> getPaths() {
return edges;
}
public void paint(Graphics2D g) {
g.setStroke(new BasicStroke(1.0f));
Vector2 nodeAv=new Vector2(nodeA.getX(), nodeA.getY());
Vector2 nodeBv=new Vector2(nodeB.getX(), nodeB.getY());
Vector2 vecDir=nodeBv.subtract(nodeAv);
Vector2 vecDirnor=vecDir.normalize();
Vector2 vecR=vecDirnor.multi(nodesize/2);
Vector2 vec90nor=new Vector2( -vecDir.y, vecDir.x).normalize();
double width=gap*(edges.size()-1);
Vector2 startPoint=nodeAv.add(vecR).add(vec90nor.multi(width/2));
Vector2 endPoint=nodeBv.subtract(vecR).add(vec90nor.multi(width/2));
//System.out.println(width);
for (Iterator<GraphEdge> iterator = edges.iterator(); iterator.hasNext();) {
GraphEdge graphEdge = (GraphEdge) iterator.next();
//System.out.println(vec90nor);
g.setColor(KLALBUtils.getColorByLoadPercentage(graphEdge.linkPath.getSpeed()*100f/graphEdge.linkPath.getBandwidth()));
if(graphEdge.from.equals( nodeA)&&graphEdge.to.equals(nodeB) )
drawAL((int)startPoint.x, (int)startPoint.y, (int)endPoint.x, (int)endPoint.y,g);
if(graphEdge.to.equals( nodeA)&&graphEdge.from.equals(nodeB) )
drawAL((int)endPoint.x, (int)endPoint.y, (int)startPoint.x, (int)startPoint.y,g);
startPoint=startPoint.subtract(vec90nor.multi(gap));
endPoint=endPoint.subtract(vec90nor.multi(gap));
}
//g.drawLine(nodeA.getX(), nodeA.getY(), nodeB.getX(), nodeB.getY());
}
public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
{
double H = 5; // 箭头高度
double L = 2; // 底边的一半
int x3 = 0;
int y3 = 0;
int x4 = 0;
int y4 = 0;
double awrad = Math.atan(L / H); // 箭头角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
double y_3 = ey - arrXY_1[1];
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
double y_4 = ey - arrXY_2[1];
Double X3 = new Double(x_3);
x3 = X3.intValue();
Double Y3 = new Double(y_3);
y3 = Y3.intValue();
Double X4 = new Double(x_4);
x4 = X4.intValue();
Double Y4 = new Double(y_4);
y4 = Y4.intValue();
// 画线
g2.drawLine(sx, sy, ex, ey);
//
GeneralPath triangle = new GeneralPath();
triangle.moveTo(ex, ey);
triangle.lineTo(x3, y3);
triangle.lineTo(x4, y4);
triangle.closePath();
//实心箭头
g2.fill(triangle);
//非实心箭头
//g2.draw(triangle);
}
// 计算
public static double[] rotateVec(int px, int py, double ang,
boolean isChLen, double newLen) {
double mathstr[] = new double[2];
// 矢量旋转函数参数含义分别是x分量y分量旋转角是否改变长度新长度
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
}
public NetworkGraphPanel(KLALBRoutingProtocol routingProtocol) {
super();
this.routingProtocol = routingProtocol;
//setSize(10000, 10000);
//setPreferredSize(getSize());
}
@Override
public void paint(Graphics g) {
super.paint(g);
loadNodes();
Graphics2D g2d=(Graphics2D)g;
for (Iterator<GraphEdgeGroup> iterator = edgeGroups.iterator(); iterator.hasNext();) {
GraphEdgeGroup graphNode = (GraphEdgeGroup) iterator.next();
graphNode.paint(g2d);
private class InetGraphNode extends GraphNode{
private InetAddress address;
public InetGraphNode() {
super();
}
public InetGraphNode(InetAddress address, Color color, double x, double y, boolean ismarked) {
super(getText(address), color, x, y, ismarked);
this.address=address;
}
private static String getText(InetAddress address2) {
String text;
if(address2 instanceof Inet6Address) {
text=KLALBUtils.parseAbbrIPv6(address2.getHostAddress());
}else {
text=address2.getHostAddress();
}
return text;
}
public InetAddress getAddress() {
return address;
}
public void setAddress(InetAddress address) {
this.address = address;
super.setText(getText(address));
}
for (Iterator<GraphNode> iterator = nodes.values().iterator(); iterator.hasNext();) {
GraphNode graphNode = (GraphNode) iterator.next();
graphNode.paint(g2d);
}
}
Random r=new Random();
private void loadNodes() {
private double nsPerPixel=1000L;
private class InetGraphEdgeGroup extends GraphEdgeGroup{
public InetGraphEdgeGroup(GraphNode nodeA, GraphNode nodeB) {
super(nodeA, nodeB);
}
public void updateLength() {
long mindelay=Long.MAX_VALUE>>2;
for (Iterator<GraphEdge> iterator = getEdges().iterator(); iterator.hasNext();) {
GraphEdge graphEdge = (GraphEdge) iterator.next();
mindelay=Math.min(mindelay, graphEdge.linkPath.getDelay());
}
setLength(mindelay/nsPerPixel);
}
}
protected void loadNodes() {
Map<Inet6Address, Long> addr= routingProtocol.getAddresses();
Set<Inet6Address> ks=addr.keySet();
for (Iterator<Inet6Address> iterator = ks.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!nodes.containsKey(inet6Address))
nodes.put(inet6Address,new GraphNode(inet6Address.getHostAddress(),Color.BLACK,r.nextInt(50,getWidth()-100),r.nextInt(50,getHeight()-50)));
}
Set<Inet6Address> kns=nodes.keySet();
if(!getNodes().containsKey(inet6Address)) {
Vector2 v2pos=super.getRandomPos();
getNodes().put(inet6Address,new InetGraphNode(inet6Address,Color.BLACK,v2pos.x,v2pos.y,inet6Address.equals(routingProtocol.getRouter().getLocator().getAddress())));
}
}
Set<Inet6Address> kns=getNodes().keySet();
for (Iterator<Inet6Address> iterator = kns.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
if(!addr.containsKey(inet6Address)) {
@@ -267,32 +109,53 @@ public class NetworkGraphPanel extends JPanel {
}
}
//System.out.println("------------------------------------");
edgeGroups.clear();
Map<Inet6Address, Set<LinkDirection>> addr1= routingProtocol.getPaths();
Set<Entry<Inet6Address, Set<LinkDirection>>> salink=addr1.entrySet();
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
Set<LinkDirection>lps=entry.getValue();
synchronized (getEdgeGroups()) {
getEdgeGroups().clear();
Map<Inet6Address, List<LinkDirection>> addr1= routingProtocol.getPaths();
Set<Entry<Inet6Address, List<LinkDirection>>> salink=addr1.entrySet();
for (Iterator<Entry<Inet6Address, List<LinkDirection>>> iterator = salink.iterator(); iterator.hasNext();) {
Entry<Inet6Address, List<LinkDirection>> entry = (Entry<Inet6Address, List<LinkDirection>>) iterator.next();
List<LinkDirection>lps=entry.getValue();
for (Iterator<LinkDirection> iterator2 = lps.iterator(); iterator2.hasNext();) {
LinkDirection linkPath = (LinkDirection) iterator2.next();
//System.out.println(linkPath);
GraphNode nfrom=nodes.get(linkPath.getFromLocator());
GraphNode nto=nodes.get(linkPath.getToLocator());
InetGraphNode nfrom=(InetGraphNode) getNodes().get(linkPath.getFromLocator());
InetGraphNode nto=(InetGraphNode) getNodes().get(linkPath.getToLocator());
if(nfrom!=null&&nto!=null) {
GraphEdgeGroup group=getGroup(nfrom, nto);
group.getPaths().add(new GraphEdge(nfrom,nto,linkPath));
GraphEdge ge=new GraphEdge(nfrom,nto,linkPath);
group.getPaths().add(ge);
}
}
}
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
((InetGraphEdgeGroup) graphEdgeGroup).updateLength();
}
}
super.loadNodes();
}
private GraphEdgeGroup getGroup(GraphNode a,GraphNode b) {
for (Iterator iterator = edgeGroups.iterator(); iterator.hasNext();) {
private GraphEdgeGroup getGroup(InetGraphNode a,InetGraphNode b) {
for (Iterator iterator = getEdgeGroups().iterator(); iterator.hasNext();) {
GraphEdgeGroup graphEdgeGroup = (GraphEdgeGroup) iterator.next();
if(graphEdgeGroup.match(a,b)) {
return graphEdgeGroup;
}
}
GraphEdgeGroup ng=new GraphEdgeGroup(a, b);
edgeGroups.add(ng);
GraphEdgeGroup ng=new InetGraphEdgeGroup(a, b);
Inet6Address aprev= routingProtocol.getDijkstraPrevNode((Inet6Address) a.getAddress());
Inet6Address bprev= routingProtocol.getDijkstraPrevNode((Inet6Address) b.getAddress());
if( b.getAddress().equals(aprev)||a.getAddress().equals(bprev)) {
ng.setShortest(true);
}
getEdgeGroups().add(ng);
return ng;
}
}
@@ -10,6 +10,7 @@ import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBUtils;
@@ -93,7 +94,7 @@ public class TPanel2 extends JPanel {
targup.setHorizontalTextPosition(SwingConstants.LEFT);
setBorder(new LineBorder(Color.LIGHT_GRAY));
setSize(720, 45);
setSize(CONST.itemwidth, CONST.linepanelheight);
setPreferredSize(getSize());
JPanel panel = new JPanel();
@@ -90,7 +90,7 @@ public class SimpleKLALBMinecraftServer {
try {
s=mpsa2.connectSocket();
MinecraftSocketBridge dsb=new MinecraftSocketBridge(pds, s);
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf().getAddress();},()->{return 23333;}));
dsb.run();
} catch (UnknownHostException e) {
// TODO 自动生成的 catch
@@ -129,7 +129,7 @@ public class SimpleKLALBMinecraftServer {
//soc.setTcpNoDelay(true);
//((KLALBVirtualSocket) soc).setCompress(1);
MinecraftSocketBridge dsb=new MinecraftSocketBridge(soc, s);
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf().getAddress();},()->{return 23333;}));
//dsb.getSab().setDelay(1);
dsb.run();
/*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc);
@@ -2,7 +2,7 @@ package org.kne.cloud.network.monitor;
import java.util.function.Consumer;
public interface MonitorData {
public interface MonitorData extends Cloneable {
public static final int OFFLINE=0;
public static final int CONNECTING=1;
public static final int ONLINE=2;
@@ -30,4 +30,6 @@ public double getReliability();
throw new IllegalArgumentException("Unknown state:"+state);
}
}
public Object clone() throws CloneNotSupportedException;
}
@@ -86,4 +86,9 @@ private TimerTask ptt=new TimerTask() {
public double getReliability() {
return reliability;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@@ -47,7 +47,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
}
protected void createTask1() {
getTimer().scheduleAtFixedRate(tmt1, 0, 1000);
getTimer().scheduleAtFixedRate(tmt1, 0, 500);
}
protected void createTask2() {
getTimer().scheduleAtFixedRate(tmt2, 0, 5000);
@@ -123,24 +123,24 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld;
inTrafficOld =inTraffic.get();
inSpeed= i*1000000000/d;
inSpeed= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld;
outTrafficOld =outTraffic.get();
outSpeed= o*1000000000/d;
outSpeed= (long) (o*1000000000.0/d);
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld;
inCounterOld =inCounter.get();
inPPS= i*1000000000/d;
inPPS= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long i=outCounter.get()-outCounterOld;
outCounterOld =outCounter.get();
outPPS= i*1000000000/d;
outPPS= (long) (i*1000000000.0/d);
}
}
if(outSpeed>=outSpeedMax) {
@@ -182,25 +182,25 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld1;
inTrafficOld1 =inTraffic.get();
inSpeedAvg= i*1000000000/d;
inSpeedAvg= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld1;
outTrafficOld1 =outTraffic.get();
outSpeedAvg= o*1000000000/d;
outSpeedAvg= (long) (o*1000000000.0/d);
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld1;
inCounterOld1 =inCounter.get();
inPPSAvg= i*1000000000/d;
inPPSAvg= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld1;
outCounterOld1 =outCounter.get();
outPPSAvg= o*1000000000/d;
outPPSAvg= (long) (o*1000000000.0/d);
}
}
@@ -218,13 +218,13 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld2;
inTrafficOld2 =inTraffic.get();
inSpeedAvg2= i*1000000000/d;
inSpeedAvg2= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld2;
outTrafficOld2 =outTraffic.get();
outSpeedAvg2= o*1000000000/d;
outSpeedAvg2= (long) (o*1000000000.0/d);
}
@@ -232,13 +232,13 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld2;
inCounterOld2 =inCounter.get();
inPPSAvg2= i*1000000000/d;
inPPSAvg2= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld2;
outCounterOld2 =outCounter.get();
outPPSAvg2= o*1000000000/d;
outPPSAvg2= (long) (o*1000000000.0/d);
}
}
+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.PINGPacket;
import org.kne.cloud.network.klalb.PONGPacket;
import org.kne.cloud.network.klalb.TESTPacket;
import org.kne.cloud.network.klalb.VADDRACKPacket;
import org.kne.cloud.network.klalb.VADDRPacket;
import org.kne.cloud.network.klalb.VADDRREQPacket;
@@ -74,12 +73,13 @@ public class Kperf implements Runnable{
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
private static long MIN_SPEED=64*1024L;
private SpeedLimiter congress = new SpeedLimiter(0,10000000L);
private SpeedLimiter congress = new SpeedLimiter(10000000L);
private long congressSpeed = 0;
private double loadPercent = 1.01;
private volatile int testSize=0;
//kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564
KLALBPacket testPacket=null;
//kperf {KLALB_Stream}[2486:1:f189:7589:f1f7:6f5e:b2eb:1]:4564
//kperf {KLALB_Stream}[2486:1::8888]:4564
@Override
public void run() {
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> {
@@ -100,14 +100,14 @@ public class Kperf implements Runnable{
System.out.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0);
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);*/
Thread.sleep(wtimes*1000);
*/
startTime=System.nanoTime();
if(targetAddress!=null) {
System.out.println("测试2/4:下载带宽测试");
test.setLimitspeed(0);
testSize=60000;
testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
@@ -118,7 +118,7 @@ public class Kperf implements Runnable{
}else {
System.out.println("测试2/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000;
testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
@@ -135,7 +135,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) {
System.out.println("测试3/4:上传带宽测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=60000;
testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
@@ -146,7 +146,7 @@ public class Kperf implements Runnable{
}else {
System.out.println("测试3/4:下载带宽测试");
test.setLimitspeed(0);
testSize=60000;
testPacket=new TESTNPacket(60000);
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
@@ -162,7 +162,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) {
System.out.println("测试2/4:下载包转发率测试");
test.setLimitspeed(0);
testSize=0;
testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
@@ -171,7 +171,7 @@ public class Kperf implements Runnable{
}else {
System.out.println("测试2/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0;
testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
@@ -186,7 +186,7 @@ public class Kperf implements Runnable{
if(targetAddress!=null) {
System.out.println("测试3/4:上传包转发率测试");
test.setLimitspeed(1000L*1024L*1024L*1024L);
testSize=0;
testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
@@ -196,7 +196,7 @@ public class Kperf implements Runnable{
}else {
System.out.println("测试3/4:下载包转发率测试");
test.setLimitspeed(0);
testSize=0;
testPacket=new TEST1Packet();
for (int i = 0; i < 30; i++) {
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
@@ -206,17 +206,19 @@ public class Kperf implements Runnable{
}
System.out.println("等待时间"+wtimes+"s");
Thread.sleep(wtimes*1000);
System.out.println("测速结束!");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("测速结束!");
System.out.println("测速被中断!");
}finally {
close();
}
});
try {
monitor.setState(MonitorData.CONNECTING);
if(link==null)
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000);
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,false,20000);
link.setSoTimeout(20000);
@@ -243,10 +245,9 @@ public class Kperf implements Runnable{
}else {
if (test.checkTransmit(testSize+3)) {
TESTPacket tp=new TESTPacket(testSize);
writePacketToKPL(tp);
KLALBPacket testp=testPacket;
if (testp!=null&&test.checkTransmit(testp.getLength())) {
writePacketToKPL(testp);
@@ -351,7 +352,7 @@ public class Kperf implements Runnable{
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
// System.out.println(congressSpeed);
break;
case KLALBPacket.TEST:
case KLALBPacket.TESTN:
break;
}
Thread.yield();
@@ -371,6 +372,7 @@ public class Kperf implements Runnable{
e.printStackTrace();
}
}
tc.interrupt();
}
}
private volatile long time = System.nanoTime();
@@ -441,7 +443,7 @@ public class Kperf implements Runnable{
private KLALBPacket readPacketFromKPL() throws IOException {
KLALBPacket packet = link.readPacket();
KLALBPacket packet = link.readKLALBPacket();
if (showpacket) {
System.out.println("RX:" + packet);
@@ -459,7 +461,7 @@ public class Kperf implements Runnable{
long length=packet.getLength();
monitor.getOutTrafficAL().addAndGet(length);
monitor.getOutPacketCounterAL().incrementAndGet();
link.writePacket(packet);
link.writeKLALBPacket(packet);
link.flush();
packet.putTimePassport("sended");
packet.printPassport();
@@ -0,0 +1,57 @@
package org.kne.cloud.network.perf;
import java.nio.ByteBuffer;
import org.kne.cloud.network.NetworkPacket;
public class MemcpyBenchmark {
public static void testArrayCopySpeed(int i) {
byte[]a=new byte[i];
byte[]b=new byte[i];
long start=System.nanoTime();
System.arraycopy(a, 0, b, 0, i);
long time=System.nanoTime()-start;
long speed=i*1000000000L/time;
System.out.println(speed/1024L/1024L+" MB/s");
}
public static void testByteBufferCopySpeed(int i) {
ByteBuffer a=ByteBuffer.allocateDirect(i);
ByteBuffer b=ByteBuffer.allocateDirect(i);
long start=System.nanoTime();
a.put(b);
long time=System.nanoTime()-start;
long speed=i*1000000000L/time;
System.out.println(speed/1024L/1024L+" MB/s");
}
public static Object un;
public static void testDirectByteBufferAllocateSpeed(int i) {
long start=System.nanoTime();
for(int ix=0;ix<10000;ix++) {
ByteBuffer a=ByteBuffer.allocateDirect(i);
un=a;
}
long time=System.nanoTime()-start;
long speed=i*1000000000L/time*10000L;
System.out.println(speed/1024L/1024L+" MB/s");
}
public static void testByteBufferAllocateSpeed(int i) {
long start=System.nanoTime();
for(int ix=0;ix<10000;ix++) {
ByteBuffer a=ByteBuffer.allocate(i);
un=a;
}
long time=System.nanoTime()-start;
long speed=i*1000000000L/time*10000L;
System.out.println(speed/1024L/1024L+" MB/s");
}
public static void testByteBufferAllocatorSpeed(int i) {
long start=System.nanoTime();
for(int ix=0;ix<10000;ix++) {
ByteBuffer a=NetworkPacket.bufferAllocator.allocate(i);
un=a;
}
long time=System.nanoTime()-start;
long speed=i*1000000000L/time*10000L;
System.out.println(speed/1024L/1024L+" MB/s");
}
}
@@ -0,0 +1,91 @@
package org.kne.cloud.network.perf;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.SocketChannelListener;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.StreamChannelKLALBPacketLink;
public class NodeBenchmark implements Runnable{
private List<NodeEntry> nodeList=new ArrayList<>();
private class NodeEntry{
private SocketChannelListener scl;
private KLALBController kc;
public SocketChannelListener getScl() {
return scl;
}
public KLALBController getKc() {
return kc;
}
public NodeEntry(SocketChannelListener scl, KLALBController kc) {
super();
this.scl = scl;
this.kc = kc;
}
}
private KLALBController klalbController;
private int nodes;
public NodeBenchmark(KLALBController klalbController,int nodes) {
this.klalbController=klalbController;
this.nodes=nodes;
}
public void run() {
Random r=new Random();
for (int i = 0; i < nodes; i++) {
KLALBController kct=new KLALBController(false);
try {
SocketChannelListener scl=new SocketChannelListener(ServerSocketChannel.open().bind(new InetSocketAddress("127.0.0.8",0)));
scl.setCon((c)->{
try {
kct.addRemoteLine(new KLALBRemoteLine(new StreamChannelKLALBPacketLink(c)));
} catch (IOException e) {
e.printStackTrace();
}
});
System.out.println("KLALBController "+i+" created,locator:"+kct.getSelf());
int size=nodeList.size();
if(size>0) {
for (int j = 0; j < 1; j++) {
int ind=r.nextInt(size);
NodeEntry ne=nodeList.get(ind);
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress((InetSocketAddress) ne.getScl().getServerSocketChannel().getLocalAddress());
kct.addRemoteLines(mpsa);
System.out.println("connect:" +ne.getKc().getSelf().getAddress());
}
}
nodeList.add(new NodeEntry( scl, kct));
Thread.sleep(100);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
NodeEntry ne=nodeList.get(0);
MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress((InetSocketAddress) ne.getScl().getServerSocketChannel().getLocalAddress());
klalbController.addRemoteLines(mpsa);
} catch (IOException e) {
e.printStackTrace();
}
}
public void startPerfing() {
ThreadTool.makeVThreadIfSupport("节点数量测试线程" ,this).start();
}
}
@@ -0,0 +1,34 @@
package org.kne.cloud.network.perf;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.klalb.KLALBPacket;
public class TEST1Packet extends KLALBPacket {
private static final int HEADER_LENGTH=1;
@Override
public long getLength() {
return HEADER_LENGTH;
}
public TEST1Packet() {
super(TEST1,HEADER_LENGTH);
}
public TEST1Packet(ByteBuffer bb) {
super(bb,HEADER_LENGTH);
}
@Override
public String toString() {
return "TEST1";
}
}
@@ -1,4 +1,4 @@
package org.kne.cloud.network.klalb;
package org.kne.cloud.network.perf;
import java.io.DataInput;
import java.io.DataInputStream;
@@ -11,8 +11,9 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.klalb.KLALBPacket;
public class TESTPacket extends KLALBPacket {
public class TESTNPacket extends KLALBPacket {
private static final int HEADER_LENGTH=3;
@@ -23,8 +24,8 @@ public class TESTPacket extends KLALBPacket {
}
public TESTPacket(int limit) {
super(TEST,HEADER_LENGTH);
public TESTNPacket(int limit) {
super(TESTN,HEADER_LENGTH);
//dataBuffer.limit(limit);
dataBuffer=ByteBuffer.allocate(limit);
}
@@ -37,7 +38,7 @@ public class TESTPacket extends KLALBPacket {
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
klalbHeader.putChar(1, (char) dataBuffer.limit());
super.writeToChannel(dto);
//System.out.println(dataBuffer);
@@ -45,7 +46,7 @@ public class TESTPacket extends KLALBPacket {
}
@Override
protected void readFromChannel(ReadableByteChannel din) throws IOException {
public void readFromChannel(ReadableByteChannel din) throws IOException {
super.readFromChannel(din);
int limit=klalbHeader.getChar(1);
//dataBuffer.clear();
@@ -59,14 +60,14 @@ public class TESTPacket extends KLALBPacket {
dataBuffer.flip();
}
public TESTPacket(ByteBuffer bb) {
public TESTNPacket(ByteBuffer bb) {
super(bb,HEADER_LENGTH);
}
@Override
public String toString() {
return "TEST["+dataBuffer.limit()+"]";
return "TESTN["+dataBuffer.limit()+"]";
}
@@ -0,0 +1,101 @@
package org.kne.cloud.network.srv6;
import java.io.EOFException;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.UUID;
import org.kne.cloud.network.klalb.IPSequence;
public class ACKSEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public ACKSEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
super(klalbHeader);
}
@Override
public String toString() {
return "ACKSEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
}
public ACKSEQSSegmentRoutingTLV(UUID ackid, boolean promise) {
super(IPv6SegmentRoutingTLV.ACKSEQS);
setUUID(ackid);
setPromise(promise);
getData().limit(22);
}
public ACKSEQSSegmentRoutingTLV(IPSequence ackid, boolean promise) {
super(IPv6SegmentRoutingTLV.ACKSEQS);
setIPSequence(ackid);
setPromise(promise);
getData().limit(22);
}
public void setUUID(UUID uuid) {
getData().putLong(6,uuid.getMostSignificantBits());
getData().putLong(14,uuid.getLeastSignificantBits());
}
public UUID getUUID() {
return new UUID(getData().getLong(6),getData().getLong(14));
}
public void setIPSequence(IPSequence ackid) {
setUUID(ackid.getUuid());
}
public IPSequence getIPSequence() {
return new IPSequence(getUUID(),isPromise());
}
@Override
public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
}
@Override
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
}
public long getSequence() {
return getData().getLong(6);
}
public void setSequence(long sequence) {
getData().putLong(6,sequence);
}
public int getFlowNumber() {
return getData().getInt(2);
}
public void setFlowNumber(int flowsequence) {
getData().putInt(2,flowsequence);
}
public void setACKIP(Inet6Address ip) {
getData().put(14, ip.getAddress());
}
public Inet6Address getACKIP() {
byte[]arr=new byte[16];
getData().get(14,arr);
try {
return (Inet6Address) Inet6Address.getByAddress(arr);
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
public boolean isPromise() {
return getData().get(0)!=0?true:false;
}
public void setPromise(boolean promise) {
if(promise) {
getData().put(0, (byte) 1);
}else {
getData().put(0, (byte) 0);
}
}
}
@@ -1,6 +1,7 @@
package org.kne.cloud.network.srv6;
public interface DijkstraAlgorithm extends Runnable{
public static final long MAX_WEIGHT=Long.MAX_VALUE/256L;
public void setGraph(long[][]pointers,long[][]heap,long startPoint) ;
public void run();
public long[] getDirection();
@@ -14,14 +14,21 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public static final int PADN=4;
public static final int HMAC=5;
public static final int SEQS=7;
public static final int ACKSEQS=8;
private int headerLength=2;
public int getHeaderLength() {
return headerLength;
}
private boolean isDefault;
protected volatile ByteBuffer header;
private ByteBuffer data;
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
this(header,true);
}
@@ -32,7 +39,10 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
super();
this.header = header;
if(isDefault&&(getType()!=PAD1)) {
this.isDefault=isDefault;
if(getType()==PAD1)
headerLength=1;
if(isDefault&&(headerLength>1)) {
data=ByteBuffer.allocate(512);
}
}
@@ -42,17 +52,19 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
super();
this.header=ByteBuffer.allocate(2);
this.isDefault=isDefault;
header.put((byte) type);
if(isDefault&&(type!=PAD1)) {
if(type==PAD1) {
headerLength=1;
}
if(isDefault&&(headerLength>1)) {
data=ByteBuffer.allocate(512);
}
}
@Override
public long getLength() {
if(getType()==PAD1)
return 1;
return header.limit()+(isDefault?data.limit():0);
return headerLength+(isDefault?data.limit():0);
}
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
@@ -74,6 +86,14 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
rtlv=new PADNSegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
case SEQS:
rtlv=new SEQSSegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
case ACKSEQS:
rtlv=new ACKSEQSSegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
return rtlv;
default:
rtlv=new IPv6SegmentRoutingTLV(bbf);
rtlv.readFromChannel(din);
@@ -84,26 +104,26 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
tlv.writeToChannel(dto);
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
if(isDefault&&(getType()!=PAD1)) {
public void writeToChannel(WritableByteChannel dto) throws IOException {
if(isDefault&&(headerLength>1)) {
setDataLength(data.limit());
}
header.limit(headerLength);
dto.write(header.slice(0,header.limit()));
if(isDefault&&(getType()!=PAD1)) {
if(isDefault&&(headerLength>1)) {
dto.write(data.slice(0, data.limit()));
}
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
header.limit(1);
while (header.hasRemaining()) {
if (din.read(header) == -1) {
throw new EOFException();
}
}
int type=getType();
if(type!=PAD1) {
if(headerLength>1) {
header.limit(2);
while (header.hasRemaining()) {
if (din.read(header) == -1) {
@@ -113,7 +133,7 @@ public class IPv6SegmentRoutingTLV extends NetworkPacket {
}
header.flip();
if(isDefault&&(getType()!=PAD1)) {
if(isDefault&&(headerLength>1)) {
data.clear();
data.limit(getDataLength());
while(data.hasRemaining()){
@@ -32,26 +32,41 @@ import java.util.concurrent.locks.ReentrantLock;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.klalb.KLALBVirtualRawSocket;
import org.kne.cloud.network.monitor.DelayMonitorData;
import org.kne.cloud.network.monitor.MonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorData;
import org.kne.cloud.network.monitor.SpeedAndTrafficMonitorDataImpl;
import org.kne.cloud.network.scanner.InetAddressRange;
import org.kne.cloud.network.te.BandwidthDistributer;
import com.google.gson.internal.Pair;
public class KLALBRoutingProtocol extends Thread{
private static final boolean debug = false;
private RouterInfo selfRouterInfo;
private Map<Inet6Address, RouterInfo> netmap=new ConcurrentHashMap<>();
private volatile Map<Inet6Address,Long>addresses;
private volatile Map<Inet6Address, Set<LinkDirection>> paths;
private volatile Map<Inet6Address, List<LinkDirection>> paths;
public static final int DEFAULT_PORT=1001;
public static final int DEFAULT_PROTOCOL_NUMBER=252;
public static final long HOTSOPT_TIMEOUT = 1000000000;
public static final int HOTSOPT_REPORT_INTERVAL = 100000000;
@@ -63,60 +78,59 @@ public class KLALBRoutingProtocol extends Thread{
this.router=router;
}
private ReentrantLock sendlock=new ReentrantLock();
//private ReentrantLock sendlock=new ReentrantLock();
private long floodTimer=System.nanoTime();
private long floodTimer2=System.nanoTime();
private long requestTimer=System.nanoTime();
@Override
public void run() {
Thread.currentThread().setName("KLALB路由协议接收线程");
getSelfRouterInfo();
DatagramSocket ds = null;
KLALBVirtualRawSocket ds = null;
try{
ds=new DatagramSocket(new InetSocketAddress(router.getLocator().getAddress(), DEFAULT_PORT) );
DatagramSocket ds2=ds;
ds=new KLALBVirtualRawSocket(router,router.getLocator().getAddress(), DEFAULT_PROTOCOL_NUMBER);
KLALBVirtualRawSocket ds2=ds;
new Thread(()->{
Thread.currentThread().setName("KLALB路由协议接收线程");
while(true) {
try {
/*List<NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
byte[]to=createLinkStatePacket(nls);
DatagramPacket dgp=new DatagramPacket(to,to.length);
for(int i=0;i<nls.length;i++) {
NetworkLink nl=(NetworkLink) nls[i];
if(!nl.isLoopBack()) {
Set<Inet6Address>neis=nl.discoverNeighbors();
for (Iterator<Inet6Address> iteratorx = neis.iterator(); iteratorx.hasNext();) {
Inet6Address addresses = (Inet6Address) iteratorx.next();
dgp.setAddress(addresses);
dgp.setPort(DEFAULT_PORT);
ds2.send(dgp);
}
}
}*/
RouterInfo slf= getSelfRouterInfo();
RouterInfo oslf=netmap.put(slf.getLocator().getAddress(), slf);
selfRouterInfo = getSelfRouterInfo();
RouterInfo oslf=netmap.put(selfRouterInfo.getLocator().getAddress(), selfRouterInfo);
noticeUpdate();
if(oslf==null||(!slf.equals(oslf))) {
//System.out.println("change:"+oslf+"\n"+slf);
/*if(oslf==null||(!selfRouterInfo.equals(oslf))) {
long cur=System.nanoTime();
if(cur-floodTimer2>5000000000L) {
//System.out.println("update10");
floodTimer2=cur;
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
}
}else {
long cur=System.nanoTime();
if(cur-floodTimer>60000000000L) {
//System.out.println("update60");
floodTimer=cur;
floodPacket(ds2, null, new RouterInfoPacket(slf,true));
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true));
}
}*/
long cur=System.nanoTime();
if(cur-floodTimer>60000000000L) {
if(debug)
System.out.println("update60");
floodTimer=cur;
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,-1));
}
Set<Inet6Address> requestSet=new HashSet<>();
if(cur-floodTimer2>1000000000L) {
if(debug)
System.out.println("update1");
floodTimer2=cur;
floodPacket(ds2, null, new RouterInfoPacket(selfRouterInfo,true,router.getASN()));
}
//Set<Inet6Address> requestSet=new HashSet<>();
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = netmap.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, RouterInfo> type = (Entry<Inet6Address, RouterInfo>) iterator.next();
RouterInfo val=type.getValue();
@@ -124,7 +138,7 @@ public class KLALBRoutingProtocol extends Thread{
iterator.remove();
noticeUpdate();
}
Set<NeighborInfo> ads=val.getNeighborAddresses();
/*List<NeighborInfo> ads=val.getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ads.iterator(); iterator2.hasNext();) {
Inet6Address address=iterator2.next().getLocator().getAddress();
//System.out.println(address);
@@ -132,35 +146,37 @@ public class KLALBRoutingProtocol extends Thread{
requestSet.add(address);
}
}
}*/
}
computeShortestPathIfUpdated();
/*long cur2=System.nanoTime();
if(cur2-requestTimer>1000000000L) {
requestTimer=cur2;
for (Iterator<Inet6Address> iterator = requestSet.iterator(); iterator.hasNext();) {
Inet6Address inet6Address = (Inet6Address) iterator.next();
byte[]to=new byte[] {0};
DatagramPacket dgp=new DatagramPacket(to,to.length);
dgp.setAddress(inet6Address);
dgp.setPort(DEFAULT_PORT);
writePacket(ds2, new RouterInfoRequestPacket( ), new InetSocketAddress(inet6Address, DEFAULT_PORT));
if(debug)
System.out.println("Request:"+inet6Address);
sendlock.lock();
try {
ds2.send(dgp);
}catch(SocketException e) {
System.out.println("Send failed:"+dgp.getAddress());
}finally {
sendlock.unlock();
}
}
}*/
for (Iterator<Entry<Inet6Address, HotspotAddressTimer>> iterator = hotspots.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, HotspotAddressTimer> type = (Entry<Inet6Address, HotspotAddressTimer>) iterator.next();
if(type.getValue().checkReportTime()) {
//System.out.println("hotspot address:"+type.getKey());
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
writePacket(ds2, new RouterInfoPacket( netmap.get(router.getLocator().getAddress()),false,-1), new InetSocketAddress(type.getKey(), DEFAULT_PORT));
}
if(type.getValue().checkTimeOut()) {
iterator.remove();
@@ -193,8 +209,16 @@ public class KLALBRoutingProtocol extends Thread{
switch(kp.getType()) {
case KLALBRoutingProtocolPacket.RINFO_REQ:
RouterInfo rifr=netmap.get(router.getLocator().getAddress());
if(rifr!=null)
writePacket(ds, new RouterInfoPacket( rifr,false), dgp.getSocketAddress());
if(debug)
System.out.println("get Request from:"+dgp.getSocketAddress());
if(rifr!=null) {
writePacket(ds, new RouterInfoPacket( rifr,false,-1), dgp.getSocketAddress());
if(debug)
System.out.println("response router info:"+rifr);
}else {
if(debug)
System.out.println("router info is null!");
}
break;
case KLALBRoutingProtocolPacket.RINFO:
@@ -237,7 +261,8 @@ public class KLALBRoutingProtocol extends Thread{
}
}
private void floodPacket(DatagramSocket ds,SocketAddress except,KLALBRoutingProtocolPacket rifp) throws IOException {
private void floodPacket(KLALBVirtualRawSocket ds2,SocketAddress except,RouterInfoPacket rifp) throws IOException {
long asn=rifp.getASN();
List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
for(int i=0;i<nls.length;i++) {
@@ -248,27 +273,31 @@ public class KLALBRoutingProtocol extends Thread{
Neighbor addresses = (Neighbor) iteratorx.next();
InetSocketAddress isa=new InetSocketAddress(addresses.getLocator().getAddress(),DEFAULT_PORT);
if(!isa.equals(except)) {
writePacket(ds, rifp, isa);
if(asn==-1) {
writePacket(ds2, rifp, isa);
}else{
RouterInfo nif= netmap.get(isa.getAddress());
if(nif!=null&&nif.getAsn()==asn) {
writePacket(ds2, rifp, isa);
}
}
}
}
}
}
}
private void writePacket(DatagramSocket ds,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
private void writePacket(KLALBVirtualRawSocket ds2,KLALBRoutingProtocolPacket pkt,SocketAddress dest) throws IOException {
ByteArrayOutputStream bos=new ByteArrayOutputStream(65535);
KLALBRoutingProtocolPacket.writeKLALBPacketToChannel(Channels.newChannel(bos),pkt);
byte[]to=bos.toByteArray();
DatagramPacket dgpx=new DatagramPacket(to,to.length);
dgpx.setSocketAddress(dest);
sendlock.lock();
try {
ds.send(dgpx);
ds2.send(dgpx);
}catch(BindException e) {
e.printStackTrace();
System.err.println("Cannot assign:"+dest);
}finally {
sendlock.unlock();
}
}
@@ -329,47 +358,51 @@ public class KLALBRoutingProtocol extends Thread{
return;
}
Set<Entry<Inet6Address, RouterInfo>> s=netmap.entrySet();
Map<Inet6Address,Long>airs=new HashMap<>();
Map<Inet6Address,Long>airs=new HashMap<>(netmap.size()+1);
List<Inet6Address>rias=new ArrayList<>();
List<Inet6Address>rias=new ArrayList<>(netmap.size()+1);
Map<Inet6Address,Set< LinkDirection>>paths=new HashMap<>();
Map<Inet6Address,List< LinkDirection>>paths=new HashMap<>();
long number=0;
for (Iterator<Entry<Inet6Address, RouterInfo>> iterator = s.iterator(); iterator.hasNext();) {
Entry<Inet6Address, RouterInfo> entry = (Entry<Inet6Address, RouterInfo>) iterator.next();
for(Entry<Inet6Address, RouterInfo> entry:s) {
if(!airs.containsKey(entry.getKey())) {
airs.put(entry.getKey(),number);
rias.add( entry.getKey());
number++;
}
Set<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
for (Iterator<NeighborInfo> iterator2 = ni.iterator(); iterator2.hasNext();) {
NeighborInfo neighborInfo = (NeighborInfo) iterator2.next();
List<NeighborInfo> ni= entry.getValue().getNeighborAddresses();
for(NeighborInfo neighborInfo :ni) {
Inet6Address ias2=neighborInfo.getLocator().getAddress();
if(!airs.containsKey(ias2)) {
airs.put(ias2,number);
rias.add( ias2);
number++;
}
Set<LinkDirection>lp1=paths.get(entry.getKey());
List<LinkDirection>lp1=paths.get(entry.getKey());
if(lp1==null) {
paths.put(entry.getKey(), lp1=new HashSet<>());
paths.put(entry.getKey(), lp1=new ArrayList<>());
}
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
lp1.add(new LinkDirection(neighborInfo.getLocal(),neighborInfo.getNeighbor(),entry.getKey(), ias2, neighborInfo.getUploadDelay(),neighborInfo.getUploadDelayMin(),neighborInfo.getUploadSpeed(),neighborInfo.getUploadSpeedMax()));
Set<LinkDirection>lp2=paths.get(ias2);
/*Set<LinkDirection>lp2=paths.get(ias2);
if(lp2==null) {
paths.put(ias2, lp2=new HashSet<>());
}
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
lp2.add( new LinkDirection(neighborInfo.getNeighbor(),neighborInfo.getLocal(),ias2,entry.getKey() , neighborInfo.getDownloadDelay(),neighborInfo.getDownloadDelayMin(),neighborInfo.getDownloadSpeed(),neighborInfo.getDownloadSpeedMax()));
*/
}
}
long[][]pointers=new long[(int) airs.size()][2];
long heappos=0;
long linknumber=0;
for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();
for(Entry<Inet6Address, List<LinkDirection>> entry:paths.entrySet()) {
/*for (Iterator<Entry<Inet6Address, Set<LinkDirection>>> iterator = paths.entrySet().iterator(); iterator.hasNext();) {
Entry<Inet6Address, Set<LinkDirection>> entry = (Entry<Inet6Address, Set<LinkDirection>>) iterator.next();*/
linknumber+=entry.getValue().size();
}
long[][]heap=new long[(int) (linknumber)][2];
@@ -377,12 +410,16 @@ public class KLALBRoutingProtocol extends Thread{
long heapindex=0;
pointers[(int) i][0]=heappos;
InetAddress ia=rias.get((int) i);
Set<LinkDirection>lks=paths.get(ia);
List<LinkDirection>lks=paths.get(ia);
if(lks!=null)
for(LinkDirection linkPath:lks) {
/*
for (Iterator<LinkDirection> iterator = lks.iterator(); iterator.hasNext();) {
LinkDirection linkPath=iterator.next();
LinkDirection linkPath=iterator.next();*/
heap[(int)(heappos+ heapindex)][0]=airs.get(linkPath.getToLocator());
heap[(int) (heappos+heapindex)][1]=linkPath.getWeight();
//heap[(int) (heappos+heapindex)][2]=linkPath.get
// heap[(int) (heappos+heapindex)][3]=0;
heapindex++;
}
@@ -391,6 +428,8 @@ public class KLALBRoutingProtocol extends Thread{
pointers[(int) i][1]=heapindex;
}
algorithm.setGraph(pointers,heap,airs.get(router.getLocator().getAddress()));
algorithm.run();
directions=new NetmapDirections(algorithm.getDirection(), rias, airs);
@@ -407,12 +446,12 @@ public class KLALBRoutingProtocol extends Thread{
private Inet6Address fromLocator;
private Inet6Address toLocator;
private long delay;
private long delayMin;
private long speed;
public long getSpeed() {
return speed;
}
private long bandwidth;
private long usedBandwidth=0;
public Inet6AddressGroup getFromAddress() {
return fromAddress;
}
@@ -425,22 +464,28 @@ public class KLALBRoutingProtocol extends Thread{
public long getBandwidth() {
return bandwidth;
}
public long getDelayMin() {
return delayMin;
}
public LinkDirection(Inet6AddressGroup fromAddress, Inet6AddressGroup toAddress, Inet6Address fromLocator,
Inet6Address toLocator,long delay,long speed, long bandwidth) {
Inet6Address toLocator, long delay, long delayMin, long speed, long bandwidth) {
super();
this.fromAddress = fromAddress;
this.toAddress = toAddress;
this.fromLocator = fromLocator;
this.toLocator = toLocator;
this.delay = delay;
this.speed=speed;
this.delayMin = delayMin;
this.speed = speed;
this.bandwidth = bandwidth;
}
@Override
public String toString() {
return "LinkDirection [fromAddress=" + fromAddress + ", toAddress=" + toAddress + ", fromLocator="
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", speed=" + speed
+ ", bandwidth=" + bandwidth + ", usedBandwidth=" + usedBandwidth + "]";
+ fromLocator + ", toLocator=" + toLocator + ", delay=" + delay + ", delayMin=" + delayMin
+ ", speed=" + speed + ", bandwidth=" + bandwidth + "]";
}
public Inet6Address getFromLocator() {
return fromLocator;
@@ -470,8 +515,7 @@ public class KLALBRoutingProtocol extends Thread{
private RouterInfo getSelfRouterInfo() {
List<IPv6NetworkLink>links=router.getLinkTabel();
Object[] nls=links.toArray();
RouterInfo ri=new RouterInfo(System.currentTimeMillis());
ri.setLocator(router.getLocator());
RouterInfo ri=new RouterInfo(System.currentTimeMillis(),router.getLocator(),router.getASN());
for(int i=0;i<nls.length;i++) {
IPv6NetworkLink nl=(IPv6NetworkLink) nls[i];
if((!nl.isLoopBack())&&nl.isUp()) {
@@ -480,6 +524,8 @@ public class KLALBRoutingProtocol extends Thread{
Neighbor addresses = (Neighbor) iteratorx.next();
long updelay=10000000000L;
long downdelay=10000000000L;
long updelayMin=10000000000L;
long downdelayMin=10000000000L;
long uploadspeed=1024L*1024;
long downloadspeed=1024L*1024;
long uploadspeedmax=1024L*1024;
@@ -489,6 +535,11 @@ public class KLALBRoutingProtocol extends Thread{
if(md instanceof DelayMonitorData) {
updelay=((DelayMonitorData) md).getOutDelay();
downdelay=((DelayMonitorData) md).getInDelay();
if(md instanceof SpeedAndTrafficAndDelayMonitorDataImpl) {
updelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getOutDelayMin();
downdelayMin=((SpeedAndTrafficAndDelayMonitorDataImpl) md).getInDelayMin();
}
}
if(md instanceof SpeedAndTrafficMonitorData) {
uploadspeed=((SpeedAndTrafficMonitorData) md).getOutSpeed();
@@ -500,7 +551,9 @@ public class KLALBRoutingProtocol extends Thread{
}
}
}
ri.getNeighborAddresses().add(new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax));
NeighborInfo ni=new NeighborInfo(nl.getAddressGroup(),addresses.getAddress(),addresses.getLocator(),updelay ,downdelay,updelayMin ,downdelayMin ,uploadspeed ,downloadspeed,uploadspeedmax ,downloadspeedmax);
ni.setContext(addresses);
ri.getNeighborAddresses().add(ni);
}
}
@@ -513,7 +566,7 @@ public class KLALBRoutingProtocol extends Thread{
public Map<Inet6Address, Long> getAddresses() {
return addresses;
}
public Map<Inet6Address, Set<LinkDirection>> getPaths() {
public Map<Inet6Address, List<LinkDirection>> getPaths() {
return paths;
}
public List<Inet6Address> createSegmentList(Inet6Address dest) {
@@ -564,12 +617,41 @@ public class KLALBRoutingProtocol extends Thread{
private Map<Inet6Address, HotspotAddressTimer> hotspots=new ConcurrentHashMap<>();
public void putHotspotAddress(Inet6Address sourceAddress) {
if(true) {
HotspotAddressTimer hat=hotspots.get(sourceAddress);
if(hat==null) {
hotspots.put(sourceAddress, new HotspotAddressTimer());
}else {
hat.refreshTimeout();
}
}
}
private Map<Inet6Address,Long> toIpBandwidth=new ConcurrentHashMap<Inet6Address,Long>();
public void updateTotalRequestBandwidth(Inet6Address targetaAddress, Long treq) {
Objects.requireNonNull(targetaAddress);
//System.out.println(""+targetaAddress.getHostAddress()+"请求带宽更新:"+treq);
if(treq<=0) {
if(toIpBandwidth.remove(targetaAddress)!=null) {
noticeUpdate();
}
}else {
Long old=toIpBandwidth.put(targetaAddress, treq);
if(old==null||old.longValue()!=treq.longValue()) {
noticeUpdate();
}
}
}
public Inet6Address getDijkstraPrevNode(Inet6Address text) {
NetmapDirections directionsx=directions;
if(directionsx==null)
return null;
long number= directionsx.getDirection_airs().get(text);
long prev= directionsx.getDirection()[(int)number];
if(prev==-1) {
return null;
}
return directionsx.getDirection_rias().get((int) prev);
}
}
@@ -34,7 +34,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
public KLALBRoutingProtocolPacket(int type) {
super();
header=NetworkPacket.databufferpool_40.borrow();
header=NetworkPacket.bufferAllocator.allocate(40);
header.put((byte) type);
}
@Override
@@ -49,7 +49,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
sndtime=System.nanoTime();
dto.write(header.slice(0, (int) getHeaderSize()));
}
@@ -59,7 +59,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
return false;
}
protected void readFromChannel(ReadableByteChannel din,long length) throws IOException {
public void readFromChannel(ReadableByteChannel din,long length) throws IOException {
rcvtime=System.nanoTime();
//System.out.println(this+" "+getHeaderSize());
header.limit((int) getHeaderSize());
@@ -89,12 +89,6 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
return header;
}
public void dispose() {
super.dispose();
/* ByteBuffer headerx=header;
header=null;
KLALBRoutingProtocolPacket.databufferpool_40.back(headerx);*/
}
public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException {
return readKLALBPacketFromChannel(Channels.newChannel(in));
@@ -102,7 +96,7 @@ public abstract class KLALBRoutingProtocolPacket extends NetworkPacket {
public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException {
while(true) {
ByteBuffer bb=databufferpool_40.borrow();
ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40);
bb.limit(1);
while(bb.hasRemaining()){
if(in.read(bb)==-1) {
@@ -11,6 +11,7 @@ import java.net.Inet6Address;
import java.util.Objects;
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
import org.kne.cloud.network.ipv6.Neighbor;
public class NeighborInfo implements Serializable {
@Override
@@ -26,13 +27,16 @@ public class NeighborInfo implements Serializable {
private Inet6AddressGroup local;
private Inet6AddressGroup neighbor;
private Inet6AddressGroup locator;
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
private transient Neighbor context;
public NeighborInfo(Inet6AddressGroup local,Inet6AddressGroup neighbor,Inet6AddressGroup locator, long uploadDelay, long downloadDelay,long uploadDelayMin, long downloadDelayMin, long uploadSpeed, long downloadSpeed, long uploadspeedmax, long downloadspeedmax) {
super();
this.local=local;
this.neighbor = neighbor;
this.locator=locator;
this.uploadDelay = uploadDelay;
this.downloadDelay = downloadDelay;
this.uploadDelayMin = uploadDelayMin;
this.downloadDelayMin= downloadDelayMin;
this.uploadSpeed = uploadSpeed;
this.downloadSpeed = downloadSpeed;
this.uploadSpeedMax=uploadspeedmax;
@@ -40,12 +44,24 @@ public class NeighborInfo implements Serializable {
}
public NeighborInfo() {
}
private long uploadDelay;
private long downloadDelay;
private long uploadDelayMin;
private long downloadDelayMin;
private long uploadSpeed;
private long downloadSpeed;
private long uploadSpeedMax;
private long downloadSpeedMax;
public void setContext(Neighbor context) {
this.context = context;
}
public Neighbor getContext() {
return context;
}
public Inet6AddressGroup getNeighbor() {
return neighbor;
}
@@ -100,6 +116,7 @@ public class NeighborInfo implements Serializable {
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
}
@Override
public int hashCode() {
return Objects.hash(local, locator, neighbor);
@@ -122,6 +139,8 @@ public class NeighborInfo implements Serializable {
locator.writeToStream(out);
out.writeLong(uploadDelay);
out.writeLong(downloadDelay);
out.writeLong(uploadDelayMin);
out.writeLong(downloadDelayMin);
out.writeLong(uploadSpeed);
out.writeLong(downloadSpeed);
out.writeLong(uploadSpeedMax);
@@ -134,9 +153,17 @@ public class NeighborInfo implements Serializable {
locator=new Inet6AddressGroup(in);
uploadDelay=in.readLong();
downloadDelay=in.readLong();
uploadDelayMin=in.readLong();
downloadDelayMin=in.readLong();
uploadSpeed=in.readLong();
downloadSpeed=in.readLong();
uploadSpeedMax=in.readLong();
downloadSpeedMax=in.readLong();
}
public long getUploadDelayMin() {
return uploadDelayMin;
}
public long getDownloadDelayMin() {
return downloadDelayMin;
}
}
@@ -4,8 +4,8 @@ import java.nio.ByteBuffer;
public class PAD1SegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public PAD1SegmentRoutingTLV(int type) {
super(type);
public PAD1SegmentRoutingTLV() {
super(IPv6SegmentRoutingTLV.PAD1);
}
public PAD1SegmentRoutingTLV(ByteBuffer klalbHeader) {
@@ -11,19 +11,20 @@ public class PADNSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
super(klalbHeader);
}
public PADNSegmentRoutingTLV(int type) {
super(type);
public PADNSegmentRoutingTLV(int dataLength) {
super(IPv6SegmentRoutingTLV.PADN);
getData().limit(dataLength);
}
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
}
+19 -7
View File
@@ -30,12 +30,20 @@ public class RouterInfo implements Serializable{
*/
private static final long serialVersionUID = 1L;
private Inet6AddressGroup locator;
private long asn;
public Inet6AddressGroup getLocator() {
return locator;
}
public void setLocator(Inet6AddressGroup locator) {
this.locator = locator;
}
public long getAsn() {
return asn;
}
public void setAsn(long asn) {
this.asn = asn;
}
@Override
public int hashCode() {
return Objects.hash(locator, neighborAddresses);
@@ -51,7 +59,7 @@ public class RouterInfo implements Serializable{
RouterInfo other = (RouterInfo) obj;
return Objects.equals(locator, other.locator) && Objects.equals(neighborAddresses, other.neighborAddresses);
}
private Set<NeighborInfo> neighborAddresses=new HashSet<>();
private List<NeighborInfo> neighborAddresses=new ArrayList<>();
private long createTime;
@@ -59,7 +67,7 @@ public class RouterInfo implements Serializable{
return createTime;
}
private static final long INFO_UPDATETIME=10000000000L;
private static final long INFO_TIMEOUT=20000000000L;
private static final long INFO_TIMEOUT=120000000000L;
private long putTime=System.nanoTime();
public boolean checkUpdateTime() {
return System.nanoTime()-putTime>INFO_UPDATETIME;
@@ -74,21 +82,24 @@ public class RouterInfo implements Serializable{
return "RINFO [locator=" + locator + ", neighborAddresses=" + neighborAddresses + ", putTime=" + putTime
+ "]";
}
public Set<NeighborInfo> getNeighborAddresses() {
public List<NeighborInfo> getNeighborAddresses() {
return neighborAddresses;
}
public RouterInfo( long createTime) {
public RouterInfo( long createTime,Inet6AddressGroup locator,long asn) {
this.createTime = createTime;
this.locator=locator;
this.asn=asn;
}
public RouterInfo() {
}
public void writeToStream(DataOutputStream out) throws IOException {
locator.writeToStream(out);
out.writeLong(asn);
out.writeLong(createTime);
out.writeInt(neighborAddresses.size());
for (Iterator iterator = neighborAddresses.iterator(); iterator.hasNext();) {
NeighborInfo neighborInfo = (NeighborInfo) iterator.next();
for( NeighborInfo neighborInfo :neighborAddresses) {
neighborInfo.writeToStream(out);
}
}
@@ -101,9 +112,10 @@ public class RouterInfo implements Serializable{
}
public void readFromStream(DataInputStream in) throws IOException {
locator=new Inet6AddressGroup(in);
asn=in.readLong();
createTime=in.readLong();
int size=in.readInt();
neighborAddresses=new HashSet<>(size);
neighborAddresses=new ArrayList<>(size);
for (int i = 0; i < size; i++) {
NeighborInfo nif=new NeighborInfo();
nif.readFromStream(in);
@@ -24,9 +24,10 @@ import org.kne.cloud.network.ipv6.Inet6AddressGroup;
public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Serializable{
public RouterInfoPacket(RouterInfo routerInfo, boolean flood) {
public RouterInfoPacket(RouterInfo routerInfo, boolean flood,long asn) {
super(RINFO);
getHeader().put(1,(byte) (flood?1:0));
getHeader().putLong(2,asn);
this.rinfo=routerInfo;
}
protected RouterInfoPacket(ByteBuffer bb) {
@@ -39,12 +40,16 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
return (getHeader().get(1)&1)==1;
}
public long getASN() {
return getHeader().getLong(2);
}
public RouterInfo getRinfo() {
return rinfo;
}
@Override
protected long getHeaderSize() {
return super.getHeaderSize()+1;
return super.getHeaderSize()+9;
}
@Override
public long getLength() {
@@ -60,12 +65,12 @@ public class RouterInfoPacket extends KLALBRoutingProtocolPacket implements Seri
@Override
protected void writeToChannel(WritableByteChannel dto) throws IOException {
public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
rinfo.writeToChannel(dto);
}
@Override
protected void readFromChannel(ReadableByteChannel din, long length) throws IOException {
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
rinfo=new RouterInfo();
rinfo.readFromChannel(din, length);
@@ -0,0 +1,98 @@
package org.kne.cloud.network.srv6;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.UUID;
public class SEQSSegmentRoutingTLV extends IPv6SegmentRoutingTLV {
public SEQSSegmentRoutingTLV(ByteBuffer klalbHeader) {
super(klalbHeader);
}
@Override
public String toString() {
return "SEQSSegmentRoutingTLV [getSequence()=" + getSequence() + "]";
}
public SEQSSegmentRoutingTLV(long sequence,UUID uuid, boolean promise,boolean keeporder/*,int flownumber,long flowsequence*/) {
super(IPv6SegmentRoutingTLV.SEQS);
setSequence(sequence);
setUUID(uuid);
setPromise(promise);
setKeepOrder(keeporder);
//setFlowNumber(flownumber);
//setFlowSequence(flowsequence);
//getData().limit(14);
//getData().limit(22);
getData().limit(30);
}
public void setUUID(UUID uuid) {
getData().putLong(14,uuid.getMostSignificantBits());
getData().putLong(22,uuid.getLeastSignificantBits());
}
public UUID getUUID() {
return new UUID(getData().getLong(14),getData().getLong(22));
}
@Override
public void writeToChannel(WritableByteChannel dto) throws IOException {
super.writeToChannel(dto);
}
@Override
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
super.readFromChannel(din, length);
}
public long getSequence() {
return getData().getLong(6);
}
public void setSequence(long sequence) {
getData().putLong(6,sequence);
}
public int getFlowNumber() {
return getData().getInt(2);
}
public void setFlowNumber(int flowsequence) {
getData().putInt(2,flowsequence);
}
/*public long getFlowSequence() {
return getData().getLong(14);
}
public void setFlowSequence(long flowsequence) {
getData().putLong(14,flowsequence);
}*/
public boolean isPromise() {
return getData().get(0)!=0?true:false;
}
public void setPromise(boolean promise) {
if(promise) {
getData().put(0, (byte) 1);
}else {
getData().put(0, (byte) 0);
}
}
public boolean isKeepOrder() {
return getData().get(1)!=0?true:false;
}
public void setKeepOrder(boolean keeporder) {
if(keeporder) {
getData().put(1, (byte) 1);
}else {
getData().put(1, (byte) 0);
}
}
}
@@ -0,0 +1,74 @@
package org.kne.cloud.network.srv6;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import org.kne.cloud.network.ipv6.IPv6Packet;
public class SRv6PacketReorder {
private PacketConsumer packetConsumer;
public SRv6PacketReorder(PacketConsumer packetConsumer) {
this.packetConsumer=packetConsumer;
}
private long jumpTime=500000000L;
private Map<Long,IPv6Packet>map=new ConcurrentHashMap<>();
private long orderTime=System.nanoTime();
private AtomicLong seqptr=new AtomicLong();
public void put(IPv6Packet pack, long sequence) throws IOException {
//System.out.println(pack.getFlowLabel()+" "+sequence);
map.put(sequence,pack);
runOrdering();
}
private ReentrantLock orderLock=new ReentrantLock();
public void runOrdering() throws IOException {
orderLock.lock();
try {
boolean whi=false;
do {
whi=false;
while(true) {
IPv6Packet i6p=map.remove(seqptr.get());
if(i6p!=null) {
//System.out.println("Ord:"+i6p.getFlowLabel()+" "+seqptr.get());
seqptr.getAndIncrement();
orderTime=System.nanoTime();
if(packetConsumer!=null) {
packetConsumer.accept(i6p);
}
}else {
break;
}
}
long ct=System.nanoTime();
if(ct-orderTime>jumpTime) {
orderTime=ct;
long l=Long.MAX_VALUE;
for(Long ent:map.keySet()) {
if(ent<l) {
l=ent;
}
}
seqptr.set(l);
whi=true;
}
}while(whi);
}finally {
orderLock.unlock();
}
}
}

Some files were not shown because too many files have changed in this diff Show More