pion / ice

A Go implementation of ICE
https://pion.ly/
MIT License
430 stars 158 forks source link

Support ipv6 for mDNS Server #642

Closed TA2k closed 4 weeks ago

TA2k commented 8 months ago

At the moment the mDNS server is not working if other service already offer mDNS service. To allow multiple mDNS server for example in multi docker systems you have to support ipv6

Please add the option to enable mDNS server via ipv6 https://github.com/pion/ice/blob/c8227261a2b808446bf181475032c54c3b509f1c/mdns.go#L46C5-L46C5

Depends on https://github.com/pion/mdns/issues/69

edaniels commented 7 months ago

mdns/v2 now supports IPv6 so it can get into ICE now! Shouldn't be too difficult but we'll need to explicitly configure it

edaniels commented 7 months ago

@TA2k do you want to take a shot at this?

It may be as simple as in mdns.go:

func createMulticastDNS(n transport.Net, networkTypes []NetworkType, mDNSMode MulticastDNSMode, mDNSName string, log logging.LeveledLogger) (*mdns.Conn, MulticastDNSMode, error) {
    if mDNSMode == MulticastDNSModeDisabled {
        return nil, mDNSMode, nil
    }

    var wantV4, wantV6 bool
    if len(networkTypes) == 0 {
        wantV4 = true
        wantV6 = true
    }
    for _, nt := range networkTypes {
        switch nt {
        case NetworkTypeTCP4, NetworkTypeUDP4:
            wantV4 = true
        case NetworkTypeTCP6, NetworkTypeUDP6:
            wantV6 = true
        }
    }
    if !(wantV4 || wantV6) {
        return nil, mDNSMode, errMulticastDNSNoUsableNetworkType
    }

    var multicastPktConnV4 *ipv4.PacketConn
    if wantV4 {
        addr4, mdnsErr := n.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
        if mdnsErr != nil {
            return nil, mDNSMode, mdnsErr
        }

        l4, mdnsErr := n.ListenUDP("udp4", addr4)
        if mdnsErr != nil {
            // If ICE fails to start MulticastDNS server just warn the user and continue
            log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode: (%s)", mdnsErr)
            return nil, MulticastDNSModeDisabled, nil
        }

        multicastPktConnV4 = ipv4.NewPacketConn(l4)
    }

    var multicastPktConnV6 *ipv6.PacketConn
    if wantV6 {
        addr6, mdnsErr := n.ResolveUDPAddr("udp6", mdns.DefaultAddressIPv6)
        if mdnsErr != nil {
            return nil, mDNSMode, mdnsErr
        }

        l6, mdnsErr := n.ListenUDP("udp6", addr6)
        if mdnsErr != nil {
            // If ICE fails to start MulticastDNS server just warn the user and continue
            log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode: (%s)", mdnsErr)
            return nil, MulticastDNSModeDisabled, nil
        }

        multicastPktConnV6 = ipv6.NewPacketConn(l6)
    }

    switch mDNSMode {
    case MulticastDNSModeQueryOnly:
        conn, err := mdns.Server(multicastPktConnV4, multicastPktConnV6, &mdns.Config{})
        return conn, mDNSMode, err
    case MulticastDNSModeQueryAndGather:
        conn, err := mdns.Server(multicastPktConnV4, multicastPktConnV6, &mdns.Config{
            LocalNames: []string{mDNSName},
        })
        return conn, mDNSMode, err
    default:
        return nil, mDNSMode, nil
    }
}

but it needs some testing around interfaces that have supported ipv6 addresses https://tools.ietf.org/html/rfc8445#section-5.1.1.1 (link-local ones which are common are not allowed for security reasons of exposing the zone (I think))

Sean-Der commented 4 weeks ago

IPv6 support was added with 39c0392295a06b5cac940f7a49d61cc74ca56c6f

thank you @edaniels !