123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
- // SPDX-License-Identifier: MIT
- package ice
- import (
- "net"
- "github.com/pion/logging"
- "github.com/pion/transport/v2"
- )
- // The conditions of invalidation written below are defined in
- // https://tools.ietf.org/html/rfc8445#section-5.1.1.1
- func isSupportedIPv6(ip net.IP) bool {
- if len(ip) != net.IPv6len ||
- isZeros(ip[0:12]) || // !(IPv4-compatible IPv6)
- ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast)
- ip.IsLinkLocalUnicast() ||
- ip.IsLinkLocalMulticast() {
- return false
- }
- return true
- }
- func isZeros(ip net.IP) bool {
- for i := 0; i < len(ip); i++ {
- if ip[i] != 0 {
- return false
- }
- }
- return true
- }
- func localInterfaces(n transport.Net, interfaceFilter func(string) bool, ipFilter func(net.IP) bool, networkTypes []NetworkType, includeLoopback bool) ([]net.IP, error) { //nolint:gocognit
- ips := []net.IP{}
- ifaces, err := n.Interfaces()
- if err != nil {
- return ips, err
- }
- var IPv4Requested, IPv6Requested bool
- for _, typ := range networkTypes {
- if typ.IsIPv4() {
- IPv4Requested = true
- }
- if typ.IsIPv6() {
- IPv6Requested = true
- }
- }
- for _, iface := range ifaces {
- if iface.Flags&net.FlagUp == 0 {
- continue // Interface down
- }
- if (iface.Flags&net.FlagLoopback != 0) && !includeLoopback {
- continue // Loopback interface
- }
- if interfaceFilter != nil && !interfaceFilter(iface.Name) {
- continue
- }
- addrs, err := iface.Addrs()
- if err != nil {
- continue
- }
- for _, addr := range addrs {
- var ip net.IP
- switch addr := addr.(type) {
- case *net.IPNet:
- ip = addr.IP
- case *net.IPAddr:
- ip = addr.IP
- }
- if ip == nil || (ip.IsLoopback() && !includeLoopback) {
- continue
- }
- if ipv4 := ip.To4(); ipv4 == nil {
- if !IPv6Requested {
- continue
- } else if !isSupportedIPv6(ip) {
- continue
- }
- } else if !IPv4Requested {
- continue
- }
- if ipFilter != nil && !ipFilter(ip) {
- continue
- }
- ips = append(ips, ip)
- }
- }
- return ips, nil
- }
- func listenUDPInPortRange(n transport.Net, log logging.LeveledLogger, portMax, portMin int, network string, lAddr *net.UDPAddr) (transport.UDPConn, error) {
- if (lAddr.Port != 0) || ((portMin == 0) && (portMax == 0)) {
- return n.ListenUDP(network, lAddr)
- }
- var i, j int
- i = portMin
- if i == 0 {
- i = 1
- }
- j = portMax
- if j == 0 {
- j = 0xFFFF
- }
- if i > j {
- return nil, ErrPort
- }
- portStart := globalMathRandomGenerator.Intn(j-i+1) + i
- portCurrent := portStart
- for {
- lAddr = &net.UDPAddr{IP: lAddr.IP, Port: portCurrent}
- c, e := n.ListenUDP(network, lAddr)
- if e == nil {
- return c, e //nolint:nilerr
- }
- log.Debugf("Failed to listen %s: %v", lAddr.String(), e)
- portCurrent++
- if portCurrent > j {
- portCurrent = i
- }
- if portCurrent == portStart {
- break
- }
- }
- return nil, ErrPort
- }
|