Wednesday, November 2, 2016

Open Visual Trace Route version 1.6.4 is out.

Version 1.6.4 is out. Here is what's new:
- Sniffer : Add feature to select a list and or range of ports.
- Sniffer : Add feature to stop the capture after a given amount of time
- Sniffer : Fix filter on port and packet length greater than 999 issue
- Traceroute : Fix traceroute timeout greater than 999 issue
- UI : German translation (thanks to Centauri39)
- UI : Japanese translation
- UI : Save table column width in preferences
- UI : Save window location
- UI : Add font chooser in the preference window
- UI : Fix sorting on row number
- Map : Choose line thickness in preference window
- Map : display unknown ips at the previous known location and no longer at (0, 0)
- Map : Fix 2D map not repainting in sniffer mode
- Windows : change whois provider
- Linux Mint : fix launcher
- Linux : add rpm packages





Tuesday, October 13, 2015

Open Visual Trace Route version 1.6.2

Open Visual Trace Route version 1.6.2 released.

Download at Sourceforge.net

Release note :Version 1.6.2 is out. Here is what's new:
- Add whois feature in both traceroute and sniffer
- Fix duplicated route points during the traceroute
- Fix command+Q failed to close the application on MacOSX
- Fix bug on sorting on tables
- Update Geoip database
- Update public ip address provider
- Fix a bunch of issues









Sunday, May 4, 2014

Open Visual Traceroute Demo video

Open Visual Trace Route version 1.5.0

Open Visual Trace Route version 1.5.0 released.

Download at Sourceforge.net

Release note :

* Add packet sniffer mode
* Add timeout for traceroute
* 2D map component using Openmap
* Upgrade to WorldWind 2.0
* Refactoring of code
* Use proper logger inside the code







Sunday, February 16, 2014

Workaround the sun.nio.cs.FastCharsetProvider bottleneck

The CharsetProvider is the class that, given a String representation of a Charset gives you the corresponding Charset object.
This is typically used when you do a new String(bytes[], "UTF-8") or a Charset.forName("UTF-8").
Looking closer at the Charset class tells us that it is actually using two levels of caches :

private static Charset lookup2(String charsetName) {
        Object[] a;
        if ((a = cache2) != null && charsetName.equals(a[0])) {
            cache2 = cache1;
            cache1 = a;
            return (Charset)a[1];
        }

        Charset cs;
        if ((cs = standardProvider.charsetForName(charsetName)) != null ||
            (cs = lookupExtendedCharset(charsetName))           != null ||
            (cs = lookupViaProviders(charsetName))              != null)
        {
            cache(charsetName, cs);
            return cs;
        }

        /* Only need to check the name if we didn't find a charset for it */
        checkName(charsetName);
        return null;
    }


and if cannot find you charset in the cache, will use the standardProvider which is a sun.nio.cs.StandardCharsets that extends sun.nio.cs.FastCharsetProvider which implementation is synchronized as you can see :

public final Charset charsetForName(String charsetName) {
        synchronized (this) {
            return lookup(canonicalize(charsetName));
        }
    }

So if you are not lucky and uses more than two different encoding, you will go to this synchronized block and create a contention point in your application, as other people talked about herehere and also in this java ticket.

To prevent this issue from happening, we can directly use a Charset object since Java 1.6 in your  code. But regarding all the library that you are using, you will have a hard time patching all of them, as mentioned in this very good post.

Or, we could just patch Java at the source, and then use whatever version of the library and of java that we want, and apply this patch to old systems as well.


package sandbox;

import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.spi.CharsetProvider;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.cliffc.high_scale_lib.NonBlockingHashMap;

import com.google.common.collect.ImmutableMap;

/**
 * NonBlockingCharsetProvider to workaround the contention point on
 * {@link CharsetProvider#charsetForName(String)}
 * 
 * @author Leo Lewis
 * @see java.nio.charset.spi.CharsetProvider
 * @see java.nio.charset.Charset
 */
public class NonBlockingCharsetProvider extends CharsetProvider {

 private CharsetProvider parent;

 private boolean lazyInit;

 private Map<String, Charset> cache;

 /**
  * @param parent
  *            parent charset provider
  * @param lazyInit
  *            if lazy init, init the cache when the application needs the
  *            charset, otherwise populate with the parent in the constructor
  *            if lazy init, will use a ConcurrentMap as it might be changed
  *            and iterated concurrently, otherwise, will use a
  *            guava Immutablehashmap
  */
 public NonBlockingCharsetProvider(final CharsetProvider parent, final boolean lazyInit) {
  this.parent = parent;
  this.lazyInit = lazyInit;
  if (!lazyInit) {
   Map<String, Charset> tmp = new HashMap<>();
   Iterator<Charset> it = parent.charsets();
   while (it.hasNext()) {
    Charset charset = it.next();
    tmp.put(charset.name(), charset);
   }
   cache = ImmutableMap.copyOf(tmp);
  } else {
   cache = new NonBlockingHashMap<>();
  }
 }

 @Override
 public Charset charsetForName(final String name) {
  Charset charset = null;
  // if not lazyInit, the value should already be in the cache
  if (lazyInit && !cache.containsKey(name)) {
   // no lock here, so we might call several times the parent and put
   // the entry into the cache, it doesn't matter as the cache will be
   // populated eventually and we won't have to call the parent anymore
   charset = parent.charsetForName(name);
   cache.put(name, charset);
  }
  return cache.get(name);
 }

 @Override
 public Iterator<Charset> charsets() {
  if (lazyInit) {
   return parent.charsets();
  }
  return cache.values().iterator();
 }

 /**
  * Save it if we want to reinstall, set up several times the provider
  */
 private static CharsetProvider standardProvider;

 /**
  * Replace the CharsetProvider into the Charset class by an instance of this
  * {@link NonBlockingCharsetProvider}
  * 
  * @param lazyInit
  *            see
  *            {@link NonBlockingCharsetProvider#NonBlockingCharsetProvider(CharsetProvider, boolean)}
  */
 public static void setUp(boolean lazyInit) throws Exception {
  Field field = Charset.class.getDeclaredField("standardProvider");
  field.setAccessible(true);
  if (standardProvider == null) {
   standardProvider = (CharsetProvider) field.get(null);
  }
  NonBlockingCharsetProvider nonBlocking = new NonBlockingCharsetProvider(standardProvider,
    lazyInit);
  field.set(null, nonBlocking);
 }

 /**
  * Restore the default java provider
  * 
  * @throws Exception
  */
 public static void uninstall() throws Exception {
  if (standardProvider != null) {
   Field field = Charset.class.getDeclaredField("standardProvider");
   field.setAccessible(true);
   field.set(null, standardProvider);
  }
 }
}

Call the NonBlockingCharsetProvider.setUp(); to replace the java provider using reflection by this non blocking one. 
This provides two modes, lazy that will get the value from the parent when necessary and put it into a concurrent non blocking hashmap (better that the standard ConcurrentHashMap), and a non lazy that get all the parent values at initialization and provides them with a thread safe guava ImmutableHashMap. Performances are pretty close for both mode, the difference is if you want to duplicate the entire Charsets supported by the JRE into the cache, or just the one that your application is using.

Et voila!


Code source is on Github
Benchmark source as well

Monday, September 16, 2013

Open Visual Traceroute 1.4.0

Open Visual Trace Route version 1.4.0 released.

Download at Sourceforge.net

Release note :
* Allow to choose the network interface to use for trace route
* Optimize startup of traceroute 
* Dramatically improve DNS lookup performance 
* Add route length and distance between route points 
* Display Country flag in the table and in the map 
* Fix the overlay of labels on the map when several route points have the same coordinates 
* Redesign gantt chart view to make it easier to see points 
* Implement selection synchronization map<->table<->gantt chart 
* Change window layout 
* Change look and feel for windows os 
* Refactor code 
* Fix an issue when replaying a route with only one point 
* Fix Linux start script 
* Fix bug when saving the size of the window



Saturday, August 10, 2013

Open Visual Trace Route 1.3

Open Visual Trace Route version 1.3 released.

* Upgrade to Worldwind 1.5.0, change layer panel, add graticule 
* Add Gantt view of the route 
* Add Replay function of the traceroute 
* Implement bi-directional selection synchronization map<->table 
* Focus on the last point of the route during tracing 
* Update visual of the Route (3d shape) 
* Update labels of the points (cities) of the route 
* Save application window size and split location when exiting the application 
* Highlight current route point during tracing (both map and table) 
* Fix an error when clearing selection the table 
* Fix an error that crashed the application when starting from a directory that has space characters inside its path 
* Fix a memory leak when tracing the route