+ * Warning:
+ * 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 java.beans 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
+ * paintDeterminate 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
+ * paintIndeterminate method.
+ * @since 1.4
+ */
+ public void paintIndeterminate(Graphics g, JComponent c) {
+ super.paintIndeterminate(g, c);
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/ListSettingItem.java b/src/org/kne/cloud/klalb/uitool/ListSettingItem.java
new file mode 100644
index 0000000..2aa3fc7
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/ListSettingItem.java
@@ -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 extends SettingItem {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ protected JList list;
+
+ private Consumer storeRecall;
+ public JList getList() {
+ return list;
+ }
+ public ListSettingItem(String text,int w,int h,XDefaultListModellm) {
+ 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 lm) {
+ super(text,deriveFont,w,h);
+ list = new JList(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) list.getModel()).addElement(v);
+ repaint();
+ if(storeRecall!=null)
+ storeRecall.accept(list.getSelectedValue());
+}
+public Consumer getStoreRecall() {
+ return storeRecall;
+}
+public void setStoreRecall(Consumer storeRecall) {
+ this.storeRecall = storeRecall;
+}
+
+}
diff --git a/src/org/kne/cloud/klalb/uitool/PathInput.java b/src/org/kne/cloud/klalb/uitool/PathInput.java
new file mode 100644
index 0000000..d3ad8f9
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/PathInput.java
@@ -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 al;
+ public Consumer getAl() {
+ return al;
+ }
+
+ public void setAl(Consumer 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);
+ }
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/RadioButtonSettingItem.java b/src/org/kne/cloud/klalb/uitool/RadioButtonSettingItem.java
new file mode 100644
index 0000000..b4567ba
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/RadioButtonSettingItem.java
@@ -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);
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/SettingItem.java b/src/org/kne/cloud/klalb/uitool/SettingItem.java
new file mode 100644
index 0000000..ccc2a74
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/SettingItem.java
@@ -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);
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/TextAreaSettingItem.java b/src/org/kne/cloud/klalb/uitool/TextAreaSettingItem.java
new file mode 100644
index 0000000..9765e6c
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/TextAreaSettingItem.java
@@ -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);
+ }
+
+}
diff --git a/src/org/kne/cloud/klalb/uitool/TextButtonSettingItem.java b/src/org/kne/cloud/klalb/uitool/TextButtonSettingItem.java
new file mode 100644
index 0000000..c95dd6a
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/TextButtonSettingItem.java
@@ -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));
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/TextSettingItem.java b/src/org/kne/cloud/klalb/uitool/TextSettingItem.java
new file mode 100644
index 0000000..296a7eb
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/TextSettingItem.java
@@ -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);
+ }
+
+}
diff --git a/src/org/kne/cloud/klalb/uitool/XAbstractListModel.java b/src/org/kne/cloud/klalb/uitool/XAbstractListModel.java
new file mode 100644
index 0000000..c91a813
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/XAbstractListModel.java
@@ -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 List with its contents.
+ *
+ * Warning:
+ * 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 java.beans package.
+ * Please see {@link java.beans.XMLEncoder}.
+ *
+ * @param the type of the elements of this model
+ *
+ * @author Hans Muller
+ * @since 1.2
+ */
+@SuppressWarnings("serial") // Same-version serialization only
+public abstract class XAbstractListModel implements ListModel, 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 ListDataListener 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 ListDataListener 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 AbstractListModel.
+ *
+ * @return all of this model's ListDataListeners,
+ * 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);
+ }
+
+
+ /**
+ * AbstractListModel subclasses must call this method
+ * after
+ * 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 ListModel 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);
+ }
+ }
+ }
+
+
+ /**
+ * AbstractListModel subclasses must call this method
+ * after
+ * 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 ListModel 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);
+ }
+ }
+ }
+
+
+ /**
+ * AbstractListModel subclasses must call this method
+ * after one or more elements are removed from the model.
+ * index0 and index1 are the end points
+ * of the interval that's been removed. Note that index0
+ * need not be less than or equal to index1.
+ *
+ * @param source the ListModel that changed, typically "this"
+ * @param index0 one end of the removed interval,
+ * including index0
+ * @param index1 the other end of the removed interval,
+ * including index1
+ * @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
+ * FooListeners
+ * upon this model.
+ * FooListeners
+ * are registered using the addFooListener method.
+ *
+ * You can specify the listenerType argument
+ * with a class literal, such as FooListener.class.
+ * For example, you can query a list model
+ * m
+ * for its list data listeners
+ * with the following code:
+ *
+ *
+ *
+ * If no such listeners exist,
+ * this method returns an empty array.
+ *
+ * @param the type of {@code EventListener} class being requested
+ * @param listenerType the type of listeners requested;
+ * this parameter should specify an interface
+ * that descends from java.util.EventListener
+ * @return an array of all objects registered as
+ * FooListeners
+ * on this model,
+ * or an empty array if no such
+ * listeners have been added
+ * @exception ClassCastException if listenerType doesn't
+ * specify a class or interface that implements
+ * java.util.EventListener
+ *
+ * @see #getListDataListeners
+ *
+ * @since 1.3
+ */
+ public T[] getListeners(Class listenerType) {
+ return listenerList.getListeners(listenerType);
+ }
+}
diff --git a/src/org/kne/cloud/klalb/uitool/XButton.java b/src/org/kne/cloud/klalb/uitool/XButton.java
new file mode 100644
index 0000000..8967699
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/XButton.java
@@ -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);
+ }
+
+}
diff --git a/src/org/kne/cloud/klalb/uitool/XDefaultListModel.java b/src/org/kne/cloud/klalb/uitool/XDefaultListModel.java
new file mode 100644
index 0000000..4832024
--- /dev/null
+++ b/src/org/kne/cloud/klalb/uitool/XDefaultListModel.java
@@ -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.
+ *
+ * Warning:
+ * 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 the type of the elements of this model
+ *
+ * @author Hans Muller
+ * @since 1.2
+ */
+@SuppressWarnings("serial") // Same-version serialization only
+public class XDefaultListModel extends XAbstractListModel implements Externalizable
+{
+ private Vector delegate = new Vector();
+
+ /**
+ * Constructs a {@code DefaultListModel}.
+ */
+ public XDefaultListModel() {}
+
+ /**
+ * Returns the number of components in this list.
+ *
+ * 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.
+ *
+ * Note: 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.
+ *
+ * @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 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.
+ *
+ * Note: 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.
+ *
+ *
+ * @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.
+ *
+ * Note: 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.
+ *
+ *
+ * @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.
+ *
+ * Note: 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.
+ *
+ *
+ * @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 index.
+ *
+ * Note: 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.
+ *
+ *
+ * @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.
+ *
+ * Note: 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.
+ *
+ *
+ * @see #clear()
+ * @see Vector#removeAllElements()
+ */
+ public void removeAllElements() {
+ int index1 = delegate.size()-1;
+ delegate.removeAllElements();
+ if (index1 >= 0) {
+ fireIntervalRemoved(this, 0, index1);
+ }
+ }
+
+
+ /**
+ * Returns a string that displays and identifies this
+ * object's properties.
+ *
+ * @return a String representation of this object
+ */
+ public String toString() {
+ return delegate.toString();
+ }
+
+
+ /* The remaining methods are included for compatibility with the
+ * Java 2 platform Vector class.
+ */
+
+ /**
+ * Returns an array containing all of the elements in this list in the
+ * correct order.
+ *
+ * @return an array containing the elements of the list
+ * @see Vector#toArray()
+ */
+ public Object[] toArray() {
+ Object[] rv = new Object[delegate.size()];
+ delegate.copyInto(rv);
+ return rv;
+ }
+
+ /**
+ * Returns the element at the specified position in this list.
+ *
+ * @param index index of element to return
+ * @return the element at the specified position in this list
+ * @throws ArrayIndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ public E get(int index) {
+ return delegate.elementAt(index);
+ }
+
+ /**
+ * Replaces the element at the specified position in this list with the
+ * specified element.
+ *
+ * @param index index of element to replace
+ * @param element element to be stored at the specified position
+ * @return the element previously at the specified position
+ * @throws ArrayIndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ public E set(int index, E element) {
+ E rv = delegate.elementAt(index);
+ delegate.setElementAt(element, index);
+ fireContentsChanged(this, index, index);
+ return rv;
+ }
+
+ /**
+ * Inserts the specified element at the specified position in this list.
+ *
+ * @param index index at which the specified element is to be inserted
+ * @param element element to be inserted
+ * @throws ArrayIndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index > size()})
+ */
+ public void add(int index, E element) {
+ delegate.insertElementAt(element, index);
+ fireIntervalAdded(this, index, index);
+ }
+
+ /**
+ * Removes the element at the specified position in this list.
+ * Returns the element that was removed from the list
+ *
+ * @param index the index of the element to removed
+ * @return the element previously at the specified position
+ * @throws ArrayIndexOutOfBoundsException if the index is out of range
+ * ({@code index < 0 || index >= size()})
+ */
+ public E remove(int index) {
+ E rv = delegate.elementAt(index);
+ delegate.removeElementAt(index);
+ fireIntervalRemoved(this, index, index);
+ return rv;
+ }
+
+ /**
+ * Removes all of the elements from this list. The list will
+ * be empty after this call returns (unless it throws an exception).
+ */
+ public void clear() {
+ int index1 = delegate.size()-1;
+ delegate.removeAllElements();
+ if (index1 >= 0) {
+ fireIntervalRemoved(this, 0, index1);
+ }
+ }
+
+ /**
+ * Deletes the components at the specified range of indexes.
+ * The removal is inclusive, so specifying a range of (1,5)
+ * removes the component at index 1 and the component at index 5,
+ * as well as all components in between.
+ *
+ * @param fromIndex the index of the lower end of the range
+ * @param toIndex the index of the upper end of the range
+ * @throws ArrayIndexOutOfBoundsException if the index was invalid
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @see #remove(int)
+ */
+ public void removeRange(int fromIndex, int toIndex) {
+ if (fromIndex > toIndex) {
+ throw new IllegalArgumentException("fromIndex must be <= toIndex");
+ }
+ for(int i = toIndex; i >= fromIndex; i--) {
+ delegate.removeElementAt(i);
+ }
+ fireIntervalRemoved(this, fromIndex, toIndex);
+ }
+
+ /**
+ * Adds all of the elements present in the collection to the list.
+ *
+ * @param c the collection which contains the elements to add
+ * @throws NullPointerException if {@code c} is null
+ */
+ public void addAll(Collection extends E> c) {
+ if (c.isEmpty()) {
+ return;
+ }
+
+ int startIndex = getSize();
+
+ delegate.addAll(c);
+ fireIntervalAdded(this, startIndex, getSize() - 1);
+ }
+
+ /**
+ * Adds all of the elements present in the collection, starting
+ * from the specified index.
+ *
+ * @param index index at which to insert the first element from the
+ * specified collection
+ * @param c the collection which contains the elements to add
+ * @throws ArrayIndexOutOfBoundsException if {@code index} does not
+ * fall within the range of number of elements currently held
+ * @throws NullPointerException if {@code c} is null
+ */
+ public void addAll(int index, Collection extends E> c) {
+ if (index < 0 || index > getSize()) {
+ throw new ArrayIndexOutOfBoundsException("index out of range: " +
+ index);
+ }
+
+ if (c.isEmpty()) {
+ return;
+ }
+
+ delegate.addAll(index, c);
+ fireIntervalAdded(this, index, index + c.size() - 1);
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(delegate);
+
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ delegate=(Vector) in.readObject();
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/ByteArrayPool.java b/src/org/kne/cloud/network/ByteArrayPool.java
similarity index 90%
rename from src/org/kne/cloud/network/klalb/ByteArrayPool.java
rename to src/org/kne/cloud/network/ByteArrayPool.java
index 3923460..ce0c41d 100644
--- a/src/org/kne/cloud/network/klalb/ByteArrayPool.java
+++ b/src/org/kne/cloud/network/ByteArrayPool.java
@@ -1,4 +1,4 @@
-package org.kne.cloud.network.klalb;
+package org.kne.cloud.network;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
diff --git a/src/org/kne/cloud/network/ByteBufferAllocator.java b/src/org/kne/cloud/network/ByteBufferAllocator.java
new file mode 100644
index 0000000..b331444
--- /dev/null
+++ b/src/org/kne/cloud/network/ByteBufferAllocator.java
@@ -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 bbfps=new ArrayList<>();
+
+ private ByteBufferPool[]bbfpsarr;
+
+
+ private ReferenceQueue 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{
+
+ private static AtomicReference first=new AtomicReference<>(null);
+
+ private AtomicReference next=new AtomicReference<>(null);
+ private AtomicReference 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();
+ }
+ }
+}
diff --git a/src/org/kne/cloud/network/ByteBufferPool.java b/src/org/kne/cloud/network/ByteBufferPool.java
new file mode 100644
index 0000000..d40e705
--- /dev/null
+++ b/src/org/kne/cloud/network/ByteBufferPool.java
@@ -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(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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/DatagramServerSocket.java b/src/org/kne/cloud/network/DatagramServerSocket.java
index 15d6486..0b5286f 100644
--- a/src/org/kne/cloud/network/DatagramServerSocket.java
+++ b/src/org/kne/cloud/network/DatagramServerSocket.java
@@ -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;
diff --git a/src/org/kne/cloud/network/IPMulticastDiscovery.java b/src/org/kne/cloud/network/IPMulticastDiscovery.java
index 5f4a807..9294e3a 100644
--- a/src/org/kne/cloud/network/IPMulticastDiscovery.java
+++ b/src/org/kne/cloud/network/IPMulticastDiscovery.java
@@ -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 msas;
private volatile Consumer 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 msas) throws IOException {
+ List 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 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();
diff --git a/src/org/kne/cloud/network/NetworkPacket.java b/src/org/kne/cloud/network/NetworkPacket.java
index 00f55d4..db1b668 100644
--- a/src/org/kne/cloud/network/NetworkPacket.java
+++ b/src/org/kne/cloud/network/NetworkPacket.java
@@ -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{
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{
}
}
- 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();
diff --git a/src/org/kne/cloud/network/PacketRebuilder.java b/src/org/kne/cloud/network/PacketRebuilder.java
index 88d7b6d..a317a37 100644
--- a/src/org/kne/cloud/network/PacketRebuilder.java
+++ b/src/org/kne/cloud/network/PacketRebuilder.java
@@ -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> iterator = recvc.entrySet().iterator(); iterator.hasNext();) {
Entry type = (Entry) 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();
}
diff --git a/src/org/kne/cloud/network/PacketSpliter.java b/src/org/kne/cloud/network/PacketSpliter.java
index 7ca7f6f..2ae626d 100644
--- a/src/org/kne/cloud/network/PacketSpliter.java
+++ b/src/org/kne/cloud/network/PacketSpliter.java
@@ -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;
}
diff --git a/src/org/kne/cloud/network/RawSocket.java b/src/org/kne/cloud/network/RawSocket.java
new file mode 100644
index 0000000..4ac51d6
--- /dev/null
+++ b/src/org/kne/cloud/network/RawSocket.java
@@ -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;
+ }
+
+}
diff --git a/src/org/kne/cloud/network/RawSocketImpl.java b/src/org/kne/cloud/network/RawSocketImpl.java
new file mode 100644
index 0000000..cb3fe4c
--- /dev/null
+++ b/src/org/kne/cloud/network/RawSocketImpl.java
@@ -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 void setOption(SocketOption name, T value) throws IOException {
+ Objects.requireNonNull(name);
+ throw new UnsupportedOperationException("'" + name + "' not supported");
+ }
+
+ protected T getOption(SocketOption 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"));
+ }
+}
diff --git a/src/org/kne/cloud/network/RawSocketImplFactory.java b/src/org/kne/cloud/network/RawSocketImplFactory.java
new file mode 100644
index 0000000..c77a7d4
--- /dev/null
+++ b/src/org/kne/cloud/network/RawSocketImplFactory.java
@@ -0,0 +1,5 @@
+package org.kne.cloud.network;
+
+public interface RawSocketImplFactory {
+ RawSocketImpl createRawSocketImpl();
+}
diff --git a/src/org/kne/cloud/network/SocketChannelListener.java b/src/org/kne/cloud/network/SocketChannelListener.java
index abfdc76..892d81b 100644
--- a/src/org/kne/cloud/network/SocketChannelListener.java
+++ b/src/org/kne/cloud/network/SocketChannelListener.java
@@ -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;
diff --git a/src/org/kne/cloud/network/SpeedLimiter.java b/src/org/kne/cloud/network/SpeedLimiter.java
index 3e7b4de..56d52ba 100644
--- a/src/org/kne/cloud/network/SpeedLimiter.java
+++ b/src/org/kne/cloud/network/SpeedLimiter.java
@@ -63,6 +63,7 @@ public class SpeedLimiter {
waitingtime.addAndGet(datasize*1000000000L/limitspeedx);
}
}
+ //用系统计时器的时刻相减得到经过的时间,与数据包除以限速值得到的应消耗的时间做对比,若时间还未到达发送下一个数据包的时机,则返回false
public boolean checkTransmit(long datasize) {
long limitspeedx=limitspeed;
if(limitspeedx<=0) {
diff --git a/src/org/kne/cloud/network/ThreadTool.java b/src/org/kne/cloud/network/ThreadTool.java
index f32949e..c87dc30 100644
--- a/src/org/kne/cloud/network/ThreadTool.java
+++ b/src/org/kne/cloud/network/ThreadTool.java
@@ -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);
+ }
+ }
}
diff --git a/src/org/kne/cloud/network/VirtualRawSocket.java b/src/org/kne/cloud/network/VirtualRawSocket.java
new file mode 100644
index 0000000..9e63dd3
--- /dev/null
+++ b/src/org/kne/cloud/network/VirtualRawSocket.java
@@ -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;
+ }
+}
diff --git a/src/org/kne/cloud/network/VirtualRawSocketImpl.java b/src/org/kne/cloud/network/VirtualRawSocketImpl.java
new file mode 100644
index 0000000..188cce3
--- /dev/null
+++ b/src/org/kne/cloud/network/VirtualRawSocketImpl.java
@@ -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 {
+
+
+
+}
diff --git a/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java b/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java
index b26423c..b36b885 100644
--- a/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java
+++ b/src/org/kne/cloud/network/ipv6/IPv6NetworkLink.java
@@ -14,10 +14,16 @@ public interface IPv6NetworkLink {
public boolean isLoopBack();
public Inet6AddressGroup getAddressGroup();
public List getNeighborsInfo();
+ public List 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(Consumercon);
+ void setRerouteConsumer(Consumer rerouteConsumer);
+ public boolean isReachSpeedLimit(IPv6Packet iPv6Packet);
}
diff --git a/src/org/kne/cloud/network/ipv6/IPv6Packet.java b/src/org/kne/cloud/network/ipv6/IPv6Packet.java
index 65ef23f..6da7cf6 100644
--- a/src/org/kne/cloud/network/ipv6/IPv6Packet.java
+++ b/src/org/kne/cloud/network/ipv6/IPv6Packet.java
@@ -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 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 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 getAddresses() {
return addresses;
}
+
+ public List 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 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 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 getHeaders() {
return headers;
}
-
+ public IPv6SegmentRoutingHeader getSRHHeader() {
+ IPv6SegmentRoutingHeader srhh = null;
+ List 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;
+ }
diff --git a/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java
index 2c7cb49..ba438e9 100644
--- a/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java
+++ b/src/org/kne/cloud/network/ipv6/IPv6TUNLoopbackNetworkLink.java
@@ -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,Listdns) 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 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 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 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 rerouteConsumer) {
+
+ }
+
+ @Override
+ public List getRouteItems() {
+ List 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 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;
+ }
}
diff --git a/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java b/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java
index 030c13e..fea8b16 100644
--- a/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java
+++ b/src/org/kne/cloud/network/ipv6/Inet6AddressGroup.java
@@ -63,13 +63,43 @@ public class Inet6AddressGroup implements Comparable{
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{
address=(Inet6Address) Inet6Address.getByAddress(b);
prefixLength=in.read();
}
+
}
diff --git a/src/org/kne/cloud/network/ipv6/Neighbor.java b/src/org/kne/cloud/network/ipv6/Neighbor.java
index e379e29..bdd53b3 100644
--- a/src/org/kne/cloud/network/ipv6/Neighbor.java
+++ b/src/org/kne/cloud/network/ipv6/Neighbor.java
@@ -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 bandwidthDistributer;
public MonitorData getMonitor() {
return monitor;
}
@@ -19,12 +22,21 @@ public class Neighbor {
public Inet6AddressGroup getLocator() {
return locator;
}
+
+ public BandwidthDistributer 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 bandwidthDistributer) {
+ this(peerAddress,remoteVaddr,monitor2);
+ this.bandwidthDistributer=bandwidthDistributer;
+ }
@Override
public String toString() {
return "Neighbor [address=" + address + ", locator=" + locator + ", monitor=" + monitor + "]";
diff --git a/src/org/kne/cloud/network/ipv6/RouteItem.java b/src/org/kne/cloud/network/ipv6/RouteItem.java
index 56ad9b4..38f6d83 100644
--- a/src/org/kne/cloud/network/ipv6/RouteItem.java
+++ b/src/org/kne/cloud/network/ipv6/RouteItem.java
@@ -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{
+public class RouteItem implements Comparable,Cloneable{
private Inet6AddressGroup destination;
private Inet6Address nexthop;
private IPv6NetworkLink destlink;
@@ -20,6 +20,7 @@ public class RouteItem implements Comparable{
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{
&& 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{
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{
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{
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{
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{
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();
+
+ }
+
}
diff --git a/src/org/kne/cloud/network/ipv6/TLV.java b/src/org/kne/cloud/network/ipv6/TLV.java
new file mode 100644
index 0000000..1ad6d81
--- /dev/null
+++ b/src/org/kne/cloud/network/ipv6/TLV.java
@@ -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);
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/ACKTPacket.java b/src/org/kne/cloud/network/klalb/ACKTPacket.java
index 5095863..8b78f56 100644
--- a/src/org/kne/cloud/network/klalb/ACKTPacket.java
+++ b/src/org/kne/cloud/network/klalb/ACKTPacket.java
@@ -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);
}
}
\ No newline at end of file
diff --git a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
index 465a302..1b4b8aa 100644
--- a/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
+++ b/src/org/kne/cloud/network/klalb/ADDLINESPacket.java
@@ -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];
diff --git a/src/org/kne/cloud/network/klalb/AbstractKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/AbstractKLALBPacketLink.java
new file mode 100644
index 0000000..75c59e8
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/AbstractKLALBPacketLink.java
@@ -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));
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/ByteBufferPool.java b/src/org/kne/cloud/network/klalb/ByteBufferPool.java
deleted file mode 100644
index 71dbeee..0000000
--- a/src/org/kne/cloud/network/klalb/ByteBufferPool.java
+++ /dev/null
@@ -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 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();
- }
- 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(pos0) {
- 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;
- }
-
-}
diff --git a/src/org/kne/cloud/network/klalb/CONST.java b/src/org/kne/cloud/network/klalb/CONST.java
index e0c8fea..eef23b2 100644
--- a/src/org/kne/cloud/network/klalb/CONST.java
+++ b/src/org/kne/cloud/network/klalb/CONST.java
@@ -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;
+
}
diff --git a/src/org/kne/cloud/network/klalb/DATATPacket.java b/src/org/kne/cloud/network/klalb/DATATPacket.java
index 5d3f6ea..833e786 100644
--- a/src/org/kne/cloud/network/klalb/DATATPacket.java
+++ b/src/org/kne/cloud/network/klalb/DATATPacket.java
@@ -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);*/
- }
}
diff --git a/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java b/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java
index 37e3da4..00629fc 100644
--- a/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java
+++ b/src/org/kne/cloud/network/klalb/DatagramKLALBPacketLink.java
@@ -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;
}
+
+
}
diff --git a/src/org/kne/cloud/network/klalb/IPSequence.java b/src/org/kne/cloud/network/klalb/IPSequence.java
new file mode 100644
index 0000000..89fa913
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/IPSequence.java
@@ -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);
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java b/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java
index 0b40c87..2c18c92 100644
--- a/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java
+++ b/src/org/kne/cloud/network/klalb/IPv6OverKLALBPacket.java
@@ -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();
- }
-
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBController.java b/src/org/kne/cloud/network/klalb/KLALBController.java
index 6c9cad2..4731719 100644
--- a/src/org/kne/cloud/network/klalb/KLALBController.java
+++ b/src/org/kne/cloud/network/klalb/KLALBController.java
@@ -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 ipmd=new ArrayList<>();
+ private ListdnsAddresses=new ArrayList<>();
+
+ public List getDnsAddresses() {
+ return dnsAddresses;
+ }
+
private Timer twk=new Timer("网卡检测扫描计时器", true);
{
@@ -210,48 +220,49 @@ public class KLALBController {
continue;
}
if(networkInterface.isUp()) {
- boolean b=true;
+
+ Enumerationei= networkInterface.getInetAddresses();
+ loop:while (ei.hasMoreElements()) {
+ InetAddress bidr = (InetAddress) ei.nextElement();
+
for (Iterator 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;
- Enumerationei= 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 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 iterator = lines.iterator(); iterator.hasNext();) {
@@ -380,7 +404,8 @@ public class KLALBController {
}
- public List addRemoteLines(MultipurposeSocketAddress target) {
+ public List addRemoteLines(MultipurposeSocketAddress target) {lineslock.writeLock().lock();
+ try {
Listadded=new ArrayList<>();
try {
Enumerationeu= NetworkInterface.getNetworkInterfaces();
@@ -419,6 +444,9 @@ public class KLALBController {
}
return added;
+ }finally {
+ lineslock.writeLock().unlock();
+ }
}
public List 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 dnsaddr) {
+ this.dnsAddresses=dnsaddr;
+ Inet6AddressGroup selfg =new Inet6AddressGroup(self, PREFIX);
+ loadSRv6ProtocolStack(selfg,enableVirtualAdapter);
+ }
+ public KLALBController(boolean enableVirtualAdapter,List 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 daddr) {
+ this(true,daddr);
+ }
+
+ public KLALBController(Inet6Address self, List 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> lines2 =new ConcurrentHashMap<>();
+ //Map> lines2 =new ConcurrentHashMap<>();
for (Iterator 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 {
ArrayListal1=new ArrayList<>();
al1.add(klalbRemoteLine);
lines2.put(klalbRemoteLine.getRemoteVaddr().getAddress(), new DWRRLoadingBalanceAlgorithm<>(al1));
- }
+ }*/
if(!srv6Router.getLinkTabel().contains(klalbRemoteLine)) {
srv6Router.getLinkTabel().add(klalbRemoteLine);
}
}
}
}
- for (Iterator>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
+ /*for (Iterator>> iterator = lines2.entrySet().iterator(); iterator.hasNext();) {
Entry> klalbRemoteLine = (Entry>) iterator.next();
List 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 l=new ArrayList();
@@ -675,122 +714,7 @@ private Timer trtr=new Timer("路由表刷新计时器", true);
lines2.put(addr, l);
}
}*/
- private Map> 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 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 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 dwrlines2x;
-
- dwrlines2x=lines2.get(addr);
-
- if (dwrlines2x == null || dwrlines2x.getEntries().isEmpty()) {
- throw new NoRouteToHostException("address unreachable: " + addr);
- }
-
- Listlines2x=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> 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 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 listens=new CopyOnWriteArrayList<>();
}
-
/*@Override
public void listen(MultipurposeSocketAddress msa) {
// TODO 自动生成的方法存根
diff --git a/src/org/kne/cloud/network/klalb/KLALBInputStream.java b/src/org/kne/cloud/network/klalb/KLALBInputStream.java
index 9a3f0d4..1a2a96a 100644
--- a/src/org/kne/cloud/network/klalb/KLALBInputStream.java
+++ b/src/org/kne/cloud/network/klalb/KLALBInputStream.java
@@ -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;
+ }
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBMain.java b/src/org/kne/cloud/network/klalb/KLALBMain.java
index 8c43720..8f610dc 100644
--- a/src/org/kne/cloud/network/klalb/KLALBMain.java
+++ b/src/org/kne/cloud/network/klalb/KLALBMain.java
@@ -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以查询命令说明");
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
index 3dbf0f4..99abf2f 100644
--- a/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
+++ b/src/org/kne/cloud/network/klalb/KLALBOutputStream.java
@@ -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);
+ }
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBPacket.java b/src/org/kne/cloud/network/klalb/KLALBPacket.java
index d5c7302..0652e29 100644
--- a/src/org/kne/cloud/network/klalb/KLALBPacket.java
+++ b/src/org/kne/cloud/network/klalb/KLALBPacket.java
@@ -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;
diff --git a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
index 4c64269..a069db6 100644
--- a/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
+++ b/src/org/kne/cloud/network/klalb/KLALBPacketLink.java
@@ -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;
diff --git a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java
index cdeda37..0db0fe4 100644
--- a/src/org/kne/cloud/network/klalb/KLALBProxySystem.java
+++ b/src/org/kne/cloud/network/klalb/KLALBProxySystem.java
@@ -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);
+ Listdaddr=new ArrayList();
+ 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);
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
index 8561b68..954f83b 100644
--- a/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
+++ b/src/org/kne/cloud/network/klalb/KLALBRemoteLine.java
@@ -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 ,LoadingBalanceEntry{
+public class KLALBRemoteLine implements IPv6NetworkLink,Comparable {
+
+ 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 {
//Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
@@ -251,87 +287,153 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable {
+ Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
+ while((!kplink.isClosed()) && (!closed)) {
+
+ Collectionvals= sendMap.values();
+ for (Iterator 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> iterator = recvedUIDMap.entrySet().iterator(); iterator.hasNext();) {
+ Entry sendItem = (Entry) 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 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= 0 && DrcvDelayFactor >= 0) {
@@ -436,7 +539,7 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable= 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 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,Comparablevals= 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 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 bwpingIntervalSleep) {
@@ -667,16 +896,25 @@ public class KLALBRemoteLine implements IPv6NetworkLink,Comparable IsendDequeList = new ConcurrentLinkedQueue();
- private PriorityBlockingQueue sendDequeList = new PriorityBlockingQueue();
+ private PriorityBlockingQueue sendDequeList = new PriorityBlockingQueue();
- public PriorityBlockingQueue getQueue() {
+ public PriorityBlockingQueue 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 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,Comparableranks=new ArrayList();
private Consumer 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 getRanks() {
-
- return ranks;
- }
@Override
public boolean isLoopBack() {
return false;
}
+ private BandwidthDistributer bandwidthDistributer=new BandwidthDistributer();
+
@Override
public List getNeighborsInfo() {
Lisths=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 sendMap= new ConcurrentHashMap<>();
+ private AtomicInteger sendmapWindowUsed=new AtomicInteger(0);
+ private MaprecvedUIDMap=new ConcurrentHashMap();
+
+ private volatile int inputchachesize = 8192 * 4000;
+ private volatile int outputchachesize = 8192 * 240;//500
+ private volatile int reallimit = 65536 ;
+ private Consumer 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 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 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,Comparable30) {
+ 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 getRouteItems() {
+ List 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 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;
+ }
+
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBUtils.java b/src/org/kne/cloud/network/klalb/KLALBUtils.java
index 1ff7c8d..467ca84 100644
--- a/src/org/kne/cloud/network/klalb/KLALBUtils.java
+++ b/src/org/kne/cloud/network/klalb/KLALBUtils.java
@@ -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 0) {
+ for (int i = start; i < end; i++) {
+ arr[i] = ":";
+ }
+ }
+ return join(arr, ":").replaceAll(":{2,}", "::");
+}
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocket.java b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocket.java
new file mode 100644
index 0000000..d389ccd
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocket.java
@@ -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);
+ }
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java
new file mode 100644
index 0000000..647a555
--- /dev/null
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualRawSocketImpl.java
@@ -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 recvQueue = new ConcurrentLinkedQueue();
+ 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);
+ }
+ }
+
+ }
+
+}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
index ca6604b..e9a7f60 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocket.java
@@ -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 {
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java
index 3c52e10..f8fcd06 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketChannel.java
@@ -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);
+ }
}
diff --git a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
index 9a87a07..84965a7 100644
--- a/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
+++ b/src/org/kne/cloud/network/klalb/KLALBVirtualSocketImpl.java
@@ -35,6 +35,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -55,13 +56,13 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
-import org.kne.acclerate.FastLib;
import org.kne.cloud.network.PortPair;
import org.kne.cloud.network.SpeedLimiter;
import org.kne.cloud.network.ThreadTool;
import org.kne.cloud.network.VirtualSocketImpl;
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
import org.kne.concurrent.SpinLock;
+import org.kne.concurrent.ThreadParker;
import org.kne.debug.TimeDebugger;
import org.kne.io.Data;
@@ -70,7 +71,8 @@ import com.google.gson.internal.Pair;
import java.util.*;
public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements BindableKLALBPacketConsumer{
-
+
+ private static final int HEADER_CALIBRATE = 40;
/*
private PrintStream dbg;
{
@@ -90,6 +92,112 @@ public class KLALBVirtualSocketImpl extends VirtualSocketImpl implements Bindabl
private KLALBController controller;
+
+ //60000 30 30
+ private final int MTU=10000;
+ private final long MIN_RTTVAR=100000000L;
+ private final long MIN_LIMIT_SPEED=128*1024L;
+ private final long REACK_INTERVAL = 100000000L;
+
+
+ private SpeedLimiter spdlmt=new SpeedLimiter(MIN_LIMIT_SPEED,2000000L);
+
+ protected Inet6Address remoteaddr;
+ protected Inet6Address localaddr;{
+ try {
+ localaddr=(Inet6Address) Inet6Address.getByName("::0");
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ }
+ //private CountDownLatch reseted=new CountDownLatch(1);
+ private BlockingQueue