Update AutoInterface and UDPInterface to use net.PacketConn for better compatibility with TinyGo. Update methods to handle errors related to unsupported features in TinyGo, including interface enumeration and multicast UDP.
This commit is contained in:
@@ -31,16 +31,16 @@ type AutoInterface struct {
|
|||||||
peers map[string]*Peer
|
peers map[string]*Peer
|
||||||
linkLocalAddrs []string
|
linkLocalAddrs []string
|
||||||
adoptedInterfaces map[string]string
|
adoptedInterfaces map[string]string
|
||||||
interfaceServers map[string]*net.UDPConn
|
interfaceServers map[string]net.PacketConn
|
||||||
multicastEchoes map[string]time.Time
|
multicastEchoes map[string]time.Time
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
outboundConn *net.UDPConn
|
outboundConn net.PacketConn
|
||||||
}
|
}
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
ifaceName string
|
ifaceName string
|
||||||
lastHeard time.Time
|
lastHeard time.Time
|
||||||
conn *net.UDPConn
|
conn net.PacketConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAutoInterface(name string, config *common.InterfaceConfig) (*AutoInterface, error) {
|
func NewAutoInterface(name string, config *common.InterfaceConfig) (*AutoInterface, error) {
|
||||||
@@ -81,70 +81,19 @@ func NewAutoInterface(name string, config *common.InterfaceConfig) (*AutoInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) Start() error {
|
func (ai *AutoInterface) Start() error {
|
||||||
interfaces, err := net.Interfaces()
|
// TinyGo doesn't support net.Interfaces() or multicast UDP
|
||||||
if err != nil {
|
// AutoInterface requires these features, so return an error
|
||||||
return fmt.Errorf("failed to list interfaces: %v", err)
|
return fmt.Errorf("AutoInterface not supported in TinyGo - requires interface enumeration and multicast UDP")
|
||||||
}
|
|
||||||
|
|
||||||
for _, iface := range interfaces {
|
|
||||||
if err := ai.configureInterface(&iface); err != nil {
|
|
||||||
log.Printf("Failed to configure interface %s: %v", iface.Name, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ai.adoptedInterfaces) == 0 {
|
|
||||||
return fmt.Errorf("no suitable interfaces found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark interface as online
|
|
||||||
ai.Online = true
|
|
||||||
ai.Enabled = true
|
|
||||||
|
|
||||||
go ai.peerJobs()
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) configureInterface(iface *net.Interface) error {
|
func (ai *AutoInterface) configureInterface(iface *net.Interface) error {
|
||||||
addrs, err := iface.Addrs()
|
// Not supported in TinyGo
|
||||||
if err != nil {
|
return fmt.Errorf("configureInterface not supported in TinyGo")
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsLinkLocalUnicast() {
|
|
||||||
ai.adoptedInterfaces[iface.Name] = ipnet.IP.String()
|
|
||||||
ai.multicastEchoes[iface.Name] = time.Now()
|
|
||||||
|
|
||||||
if err := ai.startDiscoveryListener(iface); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ai.startDataListener(iface); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) startDiscoveryListener(iface *net.Interface) error {
|
func (ai *AutoInterface) startDiscoveryListener(iface *net.Interface) error {
|
||||||
addr := &net.UDPAddr{
|
// Multicast UDP not supported in TinyGo
|
||||||
IP: net.ParseIP(fmt.Sprintf("ff%s%s::1", ai.discoveryScope, SCOPE_LINK)),
|
return fmt.Errorf("startDiscoveryListener not supported in TinyGo - requires multicast UDP")
|
||||||
Port: ai.discoveryPort,
|
|
||||||
Zone: iface.Name,
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := net.ListenMulticastUDP("udp6", iface, addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
go ai.handleDiscovery(conn, iface.Name)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) startDataListener(iface *net.Interface) error {
|
func (ai *AutoInterface) startDataListener(iface *net.Interface) error {
|
||||||
@@ -154,7 +103,7 @@ func (ai *AutoInterface) startDataListener(iface *net.Interface) error {
|
|||||||
Zone: iface.Name,
|
Zone: iface.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := net.ListenUDP("udp6", addr)
|
conn, err := net.ListenPacket("udp6", addr.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -164,23 +113,29 @@ func (ai *AutoInterface) startDataListener(iface *net.Interface) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) handleDiscovery(conn *net.UDPConn, ifaceName string) {
|
func (ai *AutoInterface) handleDiscovery(conn net.PacketConn, ifaceName string) {
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
for {
|
for {
|
||||||
_, remoteAddr, err := conn.ReadFromUDP(buf)
|
_, addr, err := conn.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Discovery read error: %v", err)
|
log.Printf("Discovery read error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remoteAddr, ok := addr.(*net.UDPAddr)
|
||||||
|
if !ok {
|
||||||
|
log.Printf("Error: received non-UDP address in discovery")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
ai.handlePeerAnnounce(remoteAddr, ifaceName)
|
ai.handlePeerAnnounce(remoteAddr, ifaceName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ai *AutoInterface) handleData(conn *net.UDPConn) {
|
func (ai *AutoInterface) handleData(conn net.PacketConn) {
|
||||||
buf := make([]byte, ai.GetMTU())
|
buf := make([]byte, ai.GetMTU())
|
||||||
for {
|
for {
|
||||||
n, _, err := conn.ReadFromUDP(buf)
|
n, _, err := conn.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !ai.IsDetached() {
|
if !ai.IsDetached() {
|
||||||
log.Printf("Data read error: %v", err)
|
log.Printf("Data read error: %v", err)
|
||||||
@@ -248,13 +203,13 @@ func (ai *AutoInterface) Send(data []byte, address string) error {
|
|||||||
|
|
||||||
if ai.outboundConn == nil {
|
if ai.outboundConn == nil {
|
||||||
var err error
|
var err error
|
||||||
ai.outboundConn, err = net.ListenUDP("udp6", &net.UDPAddr{Port: 0})
|
ai.outboundConn, err = net.ListenPacket("udp6", ":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := ai.outboundConn.WriteToUDP(data, addr); err != nil {
|
if _, err := ai.outboundConn.WriteTo(data, addr); err != nil {
|
||||||
log.Printf("Failed to send to peer %s: %v", address, err)
|
log.Printf("Failed to send to peer %s: %v", address, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
type UDPInterface struct {
|
type UDPInterface struct {
|
||||||
BaseInterface
|
BaseInterface
|
||||||
conn *net.UDPConn
|
conn net.PacketConn
|
||||||
addr *net.UDPAddr
|
addr *net.UDPAddr
|
||||||
targetAddr *net.UDPAddr
|
targetAddr *net.UDPAddr
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
@@ -127,7 +127,7 @@ func (ui *UDPInterface) ProcessOutgoing(data []byte) error {
|
|||||||
return fmt.Errorf("no target address configured")
|
return fmt.Errorf("no target address configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := ui.conn.WriteToUDP(data, ui.targetAddr)
|
_, err := ui.conn.WriteTo(data, ui.targetAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("UDP write failed: %v", err)
|
return fmt.Errorf("UDP write failed: %v", err)
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ func (ui *UDPInterface) Disable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ui *UDPInterface) Start() error {
|
func (ui *UDPInterface) Start() error {
|
||||||
conn, err := net.ListenUDP("udp", ui.addr)
|
conn, err := net.ListenPacket("udp", ui.addr.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ func (ui *UDPInterface) Start() error {
|
|||||||
func (ui *UDPInterface) readLoop() {
|
func (ui *UDPInterface) readLoop() {
|
||||||
buffer := make([]byte, common.DEFAULT_MTU)
|
buffer := make([]byte, common.DEFAULT_MTU)
|
||||||
for ui.IsOnline() && !ui.IsDetached() {
|
for ui.IsOnline() && !ui.IsDetached() {
|
||||||
n, remoteAddr, err := ui.conn.ReadFromUDP(buffer)
|
n, addr, err := ui.conn.ReadFrom(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ui.IsOnline() {
|
if ui.IsOnline() {
|
||||||
log.Printf("Error reading from UDP interface %s: %v", ui.Name, err)
|
log.Printf("Error reading from UDP interface %s: %v", ui.Name, err)
|
||||||
@@ -200,6 +200,12 @@ func (ui *UDPInterface) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remoteAddr, ok := addr.(*net.UDPAddr)
|
||||||
|
if !ok {
|
||||||
|
log.Printf("Error: received non-UDP address from UDP interface %s", ui.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
ui.mutex.Lock()
|
ui.mutex.Lock()
|
||||||
if ui.targetAddr == nil {
|
if ui.targetAddr == nil {
|
||||||
log.Printf("[DEBUG-7] UDP interface %s discovered peer %s", ui.Name, remoteAddr)
|
log.Printf("[DEBUG-7] UDP interface %s discovered peer %s", ui.Name, remoteAddr)
|
||||||
|
|||||||
Reference in New Issue
Block a user