Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make hardware address fallback more robust #6

Merged

Conversation

r0man
Copy link
Contributor

@r0man r0man commented Apr 14, 2016

The following code returns nil on my Linux machine, because the network
interface for "localhost", the loopback device, doesn't have a hardware
address.

(-> (InetAddress/getLocalHost)
     NetworkInterface/getByInetAddress
    .getHardwareAddress)

This patch uses the same fallback strategy that is used when an
UnknownHostException exception happens.

The following code returns nil on my Linux machine, because the network
interface for "localhost", the loopback device, doesn't have a hardware
address.

``` clojure
(-> (InetAddress/getLocalHost)
     NetworkInterface/getByInetAddress
    .getHardwareAddress)
```

This patch uses the same fallback strategy that is used when an
UnknownHostException exception happens.
@maxcountryman
Copy link
Owner

Thanks!

@maxcountryman maxcountryman merged commit c81bbcf into maxcountryman:master Apr 14, 2016
@r0man
Copy link
Contributor Author

r0man commented Apr 14, 2016

@maxcountryman Could you also cut a release, please? I came accross this issue while trying to use https://github.com/xsc/kithara, and I thing @xsc would also be interested in this patch. Thanks!

@maxcountryman
Copy link
Owner

maxcountryman commented Apr 14, 2016

@r0man I think I need to change how we look for hardware addresses. Do you mind telling me if this var is nil on your machine with the loopback interface?

(import '[java.net InetAddress NetworkInterface])
(def hardware-address
  (some->> (NetworkInterface/getNetworkInterfaces)
               enumeration-seq
               (remove #(.isLoopback %))
               (map #(.getHardwareAddress %))
               (filter identity)
               first))

@r0man
Copy link
Contributor Author

r0man commented Apr 15, 2016

@maxcountryman This returns the hardware address of my docker0 device, which is up but not running.

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 0.0.0.0
        ether 02:42:42:61:cb:85  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 16532  bytes 2021646 (1.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16532  bytes 2021646 (1.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.20.105  netmask 255.255.255.0  broadcast 192.168.20.255
        inet6 fe80::baf6:b1ff:fe18:1e3f  prefixlen 64  scopeid 0x20<link>
        ether b8:f6:b1:18:1e:3f  txqueuelen 1000  (Ethernet)
        RX packets 100165  bytes 125363331 (119.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 997
        TX packets 84754  bytes 8177259 (7.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 17  

Maybe filter also by isUp? This returns the hardware address of my wifi device wlp4s0.

(def hardware-address
  (some->> (NetworkInterface/getNetworkInterfaces)
               enumeration-seq
               (remove #(.isLoopback %))
               (filter #(.isUp %))
               (map #(.getHardwareAddress %))
               (filter identity)
               first))

@maxcountryman
Copy link
Owner

@r0man the Erlang implementation doesn't seem concerned with whether the interface is running or not, only that it has a non-null MAC and that the MAC isn't 0.0.0.0.0.0. I think it wouldn't be unreasonable to filter by .isVirtual as well.

But I worry that by adding filters we risk failing to find a valid MAC more frequently than we should. (It's worth pointing out that the Erlang implementation does not fallback to a random array of bytes.)

@maxcountryman
Copy link
Owner

@r0man what about something like this, which closely mirrors the Erlang implementation?

(def ifs (->> (NetworkInterface/getNetworkInterfaces)
              enumeration-seq
              (map #(.getHardwareAddress %))
              (filter identity)
              (remove #(every? zero? %))))

This will return any interface which has a non-null and non-zeroed MAC address. If we can make a case for applying further filters, as you suggest above, I'm open to that possibility as well provided we can ensure it doesn't mean we hit the SecureRandom fallback more frequently.

@r0man
Copy link
Contributor Author

r0man commented Apr 15, 2016

@maxcountryman Sounds good. Thanks for looking into this again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants