changeset 1081:dd0dad00725c

UnidirectionalRawPacketEmitter - performance improvements + bugfixes
author Devel 2
date Wed, 29 Apr 2020 15:47:36 +0200
parents f93f0bfb7338
children b09fd168aeab
files stress-tester/src/main/java/com/passus/st/emitter/EmitterUtils.java stress-tester/src/main/java/com/passus/st/emitter/raw/PcapUnidirectionalRawPacketWorker.java stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketEmitter.java stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketWorker.java
diffstat 4 files changed, 39 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/emitter/EmitterUtils.java	Wed Apr 29 14:46:07 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/emitter/EmitterUtils.java	Wed Apr 29 15:47:36 2020 +0200
@@ -11,6 +11,7 @@
 import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
 
@@ -20,6 +21,8 @@
 
     public static final String LOOPBACK_DEVICE_NAME = "lo";
 
+    private static List<NetworkInterface> netIfcs;
+
     private EmitterUtils() {
     }
 
@@ -78,10 +81,21 @@
         }
     }
 
+    private synchronized static List<NetworkInterface> getNetworkIfcs() throws SocketException {
+        if (netIfcs == null) {
+            netIfcs = new ArrayList<>();
+            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
+            while (nets.hasMoreElements()) {
+                netIfcs.add(nets.nextElement());
+            }
+        }
+
+        return netIfcs;
+    }
+
     public static NetworkInterface findFirstUpNetworkInterface() throws SocketException {
-        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
-        while (nets.hasMoreElements()) {
-            NetworkInterface ni = nets.nextElement();
+        List<NetworkInterface> networkIfcs = getNetworkIfcs();
+        for (NetworkInterface ni : networkIfcs) {
             Enumeration<InetAddress> addrs = ni.getInetAddresses();
             while (addrs.hasMoreElements()) {
                 InetAddress addr = addrs.nextElement();
@@ -102,9 +116,8 @@
     }
 
     public static NetworkInterface findNetworkInterface(IpAddress address) throws SocketException {
-        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
-        while (nets.hasMoreElements()) {
-            NetworkInterface ni = nets.nextElement();
+        List<NetworkInterface> networkIfcs = getNetworkIfcs();
+        for (NetworkInterface ni : networkIfcs) {
             List<InterfaceAddress> addrs = ni.getInterfaceAddresses();
             for (InterfaceAddress ifcAddr : addrs) {
                 IpAddress nAddr = AddressUtils.getIpAddress(ifcAddr.getAddress().getAddress());
--- a/stress-tester/src/main/java/com/passus/st/emitter/raw/PcapUnidirectionalRawPacketWorker.java	Wed Apr 29 14:46:07 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/emitter/raw/PcapUnidirectionalRawPacketWorker.java	Wed Apr 29 15:47:36 2020 +0200
@@ -1,6 +1,5 @@
 package com.passus.st.emitter.raw;
 
-import com.passus.config.schema.MapNodeDefinition;
 import com.passus.pcap.Pcap;
 import com.passus.pcap.PcapDumper;
 import com.passus.pcap.PcapIfc;
@@ -13,15 +12,14 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef;
-import static com.passus.config.schema.ConfigurationSchemaBuilder.valueDef;
-
 class PcapUnidirectionalRawPacketWorker extends UnidirectionalRawPacketWorker<PcapOutput> {
 
     private final Map<String, PcapInstance> pcaps = new HashMap<>();
 
     private String dumpFile;
 
+    private PcapIfc[] pcapIfcs;
+
     public String getDumpFile() {
         return dumpFile;
     }
@@ -35,7 +33,10 @@
         if (SystemUtils.IS_OS_WINDOWS) {
             byte[] ifcMac = ifc.getHardwareAddress();
             StringBuilder sb = new StringBuilder();
-            PcapIfc[] pcapIfcs = Pcap.listAvailableDevices(sb);
+            if (pcapIfcs == null) {
+                pcapIfcs = Pcap.listAvailableDevices(sb);
+            }
+
             for (int i = 0; i < pcapIfcs.length; i++) {
                 PcapIfc pcapIfc = pcapIfcs[i];
                 byte[] pcapIfcMac = Pcap.getHardwareAddress(pcapIfc.name);
@@ -45,6 +46,7 @@
             }
         }
 
+
         return ifc.getName();
     }
 
@@ -52,6 +54,7 @@
     protected PcapOutput doInitEngine(UnidirectionalRawPacketChannelContext<PcapOutput> channelContext, String device) throws IOException {
         PcapInstance pcapInstance = pcaps.get(device);
         if (pcapInstance == null) {
+            long start = System.currentTimeMillis();
             StringBuilder sb = new StringBuilder();
             Pcap pcap = Pcap.openLive(device, sb);
             if (pcap == null) {
@@ -70,9 +73,11 @@
                 pcapInstance = new PcapInstance(new PcapOutput.Writer(pcap, pcapDumper));
             }
 
+            LOGGER.debug("Pcap init time {}ms for device {}.", System.currentTimeMillis() - start, device);
             pcaps.put(device, pcapInstance);
         }
 
+        pcapInstance.borrows++;
         return pcapInstance.pcap;
     }
 
--- a/stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketEmitter.java	Wed Apr 29 14:46:07 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketEmitter.java	Wed Apr 29 15:47:36 2020 +0200
@@ -23,7 +23,7 @@
     protected final Logger logger = LogManager.getLogger(getClass());
 
     private static final int DEFAULT_THREADS = 1;
-    private static final int DEFAULT_MTU = 1500;
+    public static final int DEFAULT_MTU = 1500;
     private static final boolean DEFAULT_COLLECT_METRICS = true;
     private static final int MIN_MTU = ETH_HEADER_LENGTH + IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH;
 
@@ -123,7 +123,7 @@
     public void configure(Configuration config, ConfigurationContext context) {
         Emitter.super.configure(config, context);
         setMacResolver((MACAddressResolver) config.get("macResolver"));
-        setThreads(config.getInteger("threads", DEFAULT_THREADS));
+        //setThreads(config.getInteger("threads", DEFAULT_THREADS));
         setMtu(config.getInteger("mtu", DEFAULT_MTU));
         setCollectMetrics(config.getBoolean("collectMetrics", DEFAULT_COLLECT_METRICS));
     }
--- a/stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketWorker.java	Wed Apr 29 14:46:07 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/emitter/raw/UnidirectionalRawPacketWorker.java	Wed Apr 29 15:47:36 2020 +0200
@@ -28,6 +28,8 @@
 import static com.passus.net.utils.AddressUtils.jdkInetAddresToIpAddress;
 import static com.passus.st.emitter.EmitterUtils.getConnectionParams;
 import static com.passus.st.emitter.SessionMapper.ANY_SOCKET;
+import static com.passus.st.emitter.raw.UnidirectionalRawPacketEmitter.DEFAULT_MTU;
+import static java.lang.System.currentTimeMillis;
 
 public abstract class UnidirectionalRawPacketWorker<E> extends Thread implements MetricSource {
 
@@ -55,7 +57,7 @@
 
     private MACAddressResolver macResolver;
 
-    private int mtu;
+    private int mtu = DEFAULT_MTU;
 
     public PortPool getPortPool() {
         return portPool;
@@ -118,7 +120,7 @@
     public void writeMetrics(MetricsContainer container) {
         if (collectMetrics) {
             synchronized (metric) {
-                container.update(System.currentTimeMillis(), metric);
+                container.update(currentTimeMillis(), metric);
                 metric.reset();
             }
         }
@@ -224,6 +226,7 @@
         SocketAddress localAddress = connParams.getBindAddress();
         MACAddress localMac;
         try {
+            long start = currentTimeMillis();
             if (localAddress == null || ANY_SOCKET.equals(localAddress)) {
                 networkInterface = findFirstUpInterface();
                 InetAddress inetAddress = networkInterface.getInetAddresses().nextElement();
@@ -232,14 +235,16 @@
             } else {
                 networkInterface = findInterface(localAddress.getIp());
             }
+            LOGGER.debug("Find ifc duration {}).", currentTimeMillis() - start);
 
             byte[] localHwAddress = networkInterface.getHardwareAddress();
             if (localHwAddress == null) {
                 localHwAddress = ZERO_MAC;
             }
             localMac = new MACAddress(localHwAddress);
+            start = currentTimeMillis();
             device = resolveDevice(networkInterface);
-            LOGGER.debug("Found device " + device + " for ifc " + networkInterface);
+            LOGGER.debug("Found device {} for ifc {} (duration {}).", device, networkInterface, currentTimeMillis() - start);
         } catch (IOException ex) {
             doCatchException(channelContext, ex);
             return;