Skip to content

Commit

Permalink
Revert "Revert "by default use the default egress interface (#44)" (#49
Browse files Browse the repository at this point in the history
…)" (#50)

This reverts commit 0d871e8.
  • Loading branch information
cowtowncoder committed Jun 18, 2022
1 parent 0d871e8 commit 255abe7
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 5 deletions.
77 changes: 72 additions & 5 deletions src/main/java/com/fasterxml/uuid/EthernetAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
package com.fasterxml.uuid;

import java.io.Serializable;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.Random;
Expand Down Expand Up @@ -271,18 +275,81 @@ public static EthernetAddress fromInterface()
while (en.hasMoreElements()) {
NetworkInterface nint = en.nextElement();
if (!nint.isLoopback()) {
byte[] data = nint.getHardwareAddress();
if (data != null && data.length == 6) {
return new EthernetAddress(data);
}
return fromInterface(nint);
}
}
} catch (java.net.SocketException e) {
// fine, let's take is as signal of not having any interfaces
}
return null;
}


/**
* A factory method to return the ethernet address of a specified network interface.
*/
public static EthernetAddress fromInterface(NetworkInterface nint)
{
try {
byte[] data = nint.getHardwareAddress();
if (data != null && data.length == 6) {
return new EthernetAddress(data);
}
} catch (SocketException e) {
// could not get address
}
return null;
}

/**
* A factory method that will try to determine the ethernet address of
* the network interface that connects to the default network gateway.
* To do this it will try to open a connection to one of the root DNS
* servers, or barring that, to adresss 1.1.1.1, or finally if that also
* fails then to IPv6 address "1::1". If a connection can be opened then
* the interface through which that connection is routed is determined
* to be the default egress interface, and the corresponding address of
* that interface will be returned. If all attempts are unsuccessful,
* null will be returned.
*/
public static EthernetAddress fromEgressInterface()
{
String roots = "abcdefghijklm";
int index = new Random().nextInt(roots.length());
String name = roots.charAt(index) + ".root-servers.net";
InetSocketAddress externalAddress = new InetSocketAddress(name, 0);
if (externalAddress.isUnresolved()) {
externalAddress = new InetSocketAddress("1.1.1.1", 0);
}
EthernetAddress ifAddr = fromEgressInterface(externalAddress);
if (ifAddr == null) {
return fromEgressInterface(new InetSocketAddress("1::1", 0));
} else {
return ifAddr;
}
}

/**
* A factory method to return the address of the interface used to route
* traffic to the specified address.
*/
public static EthernetAddress fromEgressInterface(InetSocketAddress externalSocketAddress)
{
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
socket.connect(externalSocketAddress);
InetAddress localAddress = socket.getLocalAddress();
NetworkInterface egressIf = NetworkInterface.getByInetAddress(localAddress);
return fromInterface(egressIf);
} catch (SocketException e) {
return null;
} finally {
if (socket != null) {
socket.close();
}
}
}

/**
* Factory method that can be used to construct a random multicast
* address; to be used in cases where there is no "real" ethernet
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/fasterxml/uuid/Generators.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public class Generators
* synchronization but no external file-based syncing.
*/
protected static UUIDTimer _sharedTimer;

/**
* The default egress network interface.
*/
protected static EthernetAddress _egressIfAddr = null;

// // Random-based generation

Expand Down Expand Up @@ -116,6 +121,18 @@ public static NameBasedGenerator nameBasedGenerator(UUID namespace, MessageDiges

// // Time+location-based generation

/**
* Factory method for constructing UUID generator that generates UUID using variant 1
* (time+location based). This method will use the ethernet address of the interface
* that routes to the default gateway. For most simple and common networking configurations
* this will be the most appropriate address to use. The default interface is determined
* by the calling {@link EthernetAddress#fromEgressInterface()}.
*/
public static TimeBasedGenerator egressTimeBasedGenerator()
{
return timeBasedGenerator(egressInterfaceAddress());
}

/**
* Factory method for constructing UUID generator that generates UUID using
* variant 1 (time+location based).
Expand Down Expand Up @@ -238,4 +255,12 @@ private static synchronized UUIDTimer sharedTimer()
}
return _sharedTimer;
}

private static synchronized EthernetAddress egressInterfaceAddress()
{
if (_egressIfAddr == null) {
_egressIfAddr = EthernetAddress.fromEgressInterface();
}
return _egressIfAddr;
}
}
41 changes: 41 additions & 0 deletions src/test/java/com/fasterxml/uuid/EthernetAddressTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package com.fasterxml.uuid;

import com.fasterxml.uuid.impl.TimeBasedGenerator;
import java.net.InetSocketAddress;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
Expand Down Expand Up @@ -1307,6 +1309,45 @@ public void testFromInterface() throws Exception
assertNotNull(addr.toString());
}

public void testFromEgressInterfaceRoot() throws Exception
{
InetSocketAddress extAddr = new InetSocketAddress("a.root-servers.net", 0);
EthernetAddress ifAddr = EthernetAddress.fromEgressInterface(extAddr);
assertNotNull(ifAddr);
assertNotNull(ifAddr.toString());
}

public void testFromEgressInterfaceIp4() throws Exception
{
InetSocketAddress extAddr = new InetSocketAddress("1.1.1.1", 0);
EthernetAddress ifAddr = EthernetAddress.fromEgressInterface(extAddr);
assertNotNull(ifAddr);
assertNotNull(ifAddr.toString());
}

public void testFromEgressInterfaceIp6() throws Exception
{
InetSocketAddress extAddr = new InetSocketAddress("1::1", 0);
EthernetAddress ifAddr = EthernetAddress.fromEgressInterface(extAddr);
assertNotNull(ifAddr);
assertNotNull(ifAddr.toString());
}

public void testFromEgressInterface() throws Exception
{
EthernetAddress ifAddr = EthernetAddress.fromEgressInterface();
assertNotNull(ifAddr);
assertNotNull(ifAddr.toString());
}

public void testDefaultTimeBasedGenerator()
{
TimeBasedGenerator generator = Generators.egressTimeBasedGenerator();
EthernetAddress ifAddr = generator.getEthernetAddress();
assertNotNull(ifAddr);
assertNotNull(ifAddr.toString());
}

public void testBogus() throws Exception
{
// First, two using pseudo-random; verify they are different
Expand Down

0 comments on commit 255abe7

Please sign in to comment.