Skip to content

Commit

Permalink
feat: Implement Java NetDriver and MDNSLockerDriver.
Browse files Browse the repository at this point in the history
Signed-off-by: jefft0 <jeff@thefirst.org>
  • Loading branch information
jefft0 committed Oct 19, 2022
1 parent 7f1d1ff commit f23c6aa
Show file tree
Hide file tree
Showing 6 changed files with 584 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ipfs.gomobile.android;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;

import core.NativeMDNSLockerDriver;

public class MDNSLockerDriver implements NativeMDNSLockerDriver {
private final Context context;
private MulticastLock multicastLock = null;

public MDNSLockerDriver(Context context) {
this.context = context;
}

public void lock() {
WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
multicastLock = wifi.createMulticastLock("BertyMDNSLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
}


public void unlock() {
if (multicastLock != null) {
multicastLock.release();
multicastLock = null;
}
}
}
72 changes: 72 additions & 0 deletions android/bridge/src/main/java/ipfs/gomobile/android/NetDriver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ipfs.gomobile.android;

import static core.Core.*;

import org.json.JSONArray;

import java.net.InterfaceAddress;
import java.net.NetworkInterface;

import java.util.Collections;

import core.NativeNetDriver;
import core.NetAddrs;
import core.NetInterface;
import core.NetInterfaces;

public class NetDriver implements NativeNetDriver {
public NetAddrs interfaceAddrs() throws Exception {
NetAddrs netaddrs = new NetAddrs();

for (NetworkInterface nif : Collections.list(NetworkInterface.getNetworkInterfaces())) {
try {
for (InterfaceAddress ia : nif.getInterfaceAddresses()) {
String[] parts = ia.toString().split("/", 0);
if (parts.length > 1) {
netaddrs.appendAddr(parts[1]);
}
}
} catch (Exception ignored) {}
}

return netaddrs;
}

public NetInterfaces interfaces() throws Exception {
NetInterfaces ifaces = new NetInterfaces();

for (NetworkInterface nif : Collections.list(NetworkInterface.getNetworkInterfaces())) {
NetInterface iface = new NetInterface();
try {
iface.copyHardwareAddr(nif.getHardwareAddress());
} catch (Exception ignored) {}

iface.setIndex(nif.getIndex());
iface.setMTU(nif.getMTU());
iface.setName(nif.getName());
if (nif.isLoopback()) {
iface.addFlag(NetFlagLoopback);
}

if (nif.isPointToPoint()) {
iface.addFlag(NetFlagPointToPoint);
}

if (nif.isUp()) {
iface.addFlag(NetFlagUp);
}

if (nif.isVirtual()) {
// iface.addFlag(Net);
}

if (nif.supportsMulticast()) {
iface.addFlag(NetFlagMulticast);
}

ifaces.append(iface);
}

return ifaces;
}
}
11 changes: 11 additions & 0 deletions go/bind/core/driver_mdnslocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core

type NativeMDNSLockerDriver interface {
Lock()
Unlock()
}

type noopNativeMDNSLockerDriver struct{}

func (*noopNativeMDNSLockerDriver) Lock() {}
func (*noopNativeMDNSLockerDriver) Unlock() {}
147 changes: 147 additions & 0 deletions go/bind/core/driver_net.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package core

import (
"fmt"
"net"
"strings"

"go.uber.org/zap"
)

type NativeNetDriver interface {
InterfaceAddrs() (*NetAddrs, error)
Interfaces() (*NetInterfaces, error)
}

type inet struct {
net NativeNetDriver
logger *zap.Logger
}

func (ia *inet) Interfaces() ([]net.Interface, error) {
ifaces, err := ia.net.Interfaces()
if err != nil {
return nil, err
}

return ifaces.Interfaces(), nil
}

func (ia *inet) InterfaceAddrs() ([]net.Addr, error) {
na, err := ia.net.InterfaceAddrs()
if err != nil {
return nil, err
}

addrs := []net.Addr{}
for _, addr := range na.addrs {
if addr == "" {
continue
}

// skip interface name
ips := strings.Split(addr, "%")
if len(ips) == 0 {
ia.logger.Debug("empty addr while parsing interface addrs")
continue
}
ip := ips[0]

// resolve ip
v, err := net.ResolveIPAddr("ip", ip)
if err != nil {
ia.logger.Warn("unable to resolve addr", zap.String("addr", ip))
continue
}

addrs = append(addrs, v)
}

fields := make([]string, len(addrs))
for i, addr := range addrs {
fields[i] = addr.String()
}

ia.logger.Debug("driver interface resolved addrs", zap.Strings("addrs", fields))
return addrs, nil
}

type NetInterfaces struct {
ifaces []*NetInterface
}

func (n *NetInterfaces) Interfaces() []net.Interface {
ifaces := make([]net.Interface, len(n.ifaces))
for i, iface := range n.ifaces {
ifaces[i] = iface.Interface()
}
return ifaces
}

func (n *NetInterfaces) Append(i *NetInterface) {
n.ifaces = append(n.ifaces, i)
}

const (
NetFlagUp int = iota // interface is up
NetFlagBroadcast // interface supports broadcast access capability
NetFlagLoopback // interface is a loopback interface
NetFlagPointToPoint // interface belongs to a point-to-point link
NetFlagMulticast // interface supports multicast access capability
)

type NetInterface struct {
Index int // positive integer that starts at one, zero is never used
MTU int // maximum transmission unit
Name string // e.g., "en0", "lo0", "eth0.100"
Addrs *NetAddrs // InterfaceAddresses

hardwareaddr []byte // IEEE MAC-48, EUI-48 and EUI-64 form
flags net.Flags // e.g., FlagUp, FlagLoopback, FlagMulticast
}

func (n *NetInterface) CopyHardwareAddr(addr []byte) {
n.hardwareaddr = make([]byte, len(n.hardwareaddr))
copy(n.hardwareaddr, addr)
}

func (n *NetInterface) Interface() net.Interface {
return net.Interface{
Index: n.Index,
MTU: n.MTU,
Name: n.Name,
HardwareAddr: n.hardwareaddr,
Flags: n.flags,
}
}

func (n *NetInterface) AddFlag(flag int) (err error) {
switch flag {
case NetFlagUp:
n.flags |= net.FlagUp
case NetFlagBroadcast:
n.flags |= net.FlagBroadcast
case NetFlagLoopback:
n.flags |= net.FlagLoopback
case NetFlagPointToPoint:
n.flags |= net.FlagPointToPoint
case NetFlagMulticast:
n.flags |= net.FlagMulticast
default:
err = fmt.Errorf("failed to add unknown flag to net interface: %d", flag)
}

return
}

type NetAddrs struct {
addrs []string
}

func NewNetAddrs() *NetAddrs {
return &NetAddrs{addrs: []string{}}
}

func (n *NetAddrs) AppendAddr(addr string) {
n.addrs = append(n.addrs, addr)
}
49 changes: 49 additions & 0 deletions go/pkg/ipfsutil/inet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ipfsutil

import (
"net"
"sync"
)

var (
muNetDriver = sync.RWMutex{}
netdriver Net = &inet{}
)

type Net interface {
NetAddrs
NetInterface
}

type NetInterface interface {
Interfaces() ([]net.Interface, error)
}

type NetAddrs interface {
InterfaceAddrs() ([]net.Addr, error)
}

var _ Net = (*inet)(nil)

type inet struct{}

func (*inet) InterfaceAddrs() ([]net.Addr, error) {
return net.InterfaceAddrs()
}

func (*inet) Interfaces() ([]net.Interface, error) {
return net.Interfaces()
}

func SetNetDriver(n Net) {
muNetDriver.Lock()
netdriver = n
muNetDriver.Unlock()
}

func getNetDriver() (n Net) {
muNetDriver.RLock()
n = netdriver
muNetDriver.RUnlock()
return
}
Loading

0 comments on commit f23c6aa

Please sign in to comment.