diff options
Diffstat (limited to 'vendor/github.com/pion/turn/v2/relay_address_generator_range.go')
-rw-r--r-- | vendor/github.com/pion/turn/v2/relay_address_generator_range.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_range.go b/vendor/github.com/pion/turn/v2/relay_address_generator_range.go new file mode 100644 index 0000000..9f95429 --- /dev/null +++ b/vendor/github.com/pion/turn/v2/relay_address_generator_range.go @@ -0,0 +1,92 @@ +package turn + +import ( + "fmt" + "net" + + "github.com/pion/randutil" + "github.com/pion/transport/vnet" +) + +// RelayAddressGeneratorPortRange can be used to only allocate connections inside a defined port range. +// Similar to the RelayAddressGeneratorStatic a static ip address can be set. +type RelayAddressGeneratorPortRange struct { + // RelayAddress is the IP returned to the user when the relay is created + RelayAddress net.IP + + // MinPort the minimum port to allocate + MinPort uint16 + // MaxPort the maximum (inclusive) port to allocate + MaxPort uint16 + + // MaxRetries the amount of tries to allocate a random port in the defined range + MaxRetries int + + // Rand the random source of numbers + Rand randutil.MathRandomGenerator + + // Address is passed to Listen/ListenPacket when creating the Relay + Address string + + Net *vnet.Net +} + +// Validate is called on server startup and confirms the RelayAddressGenerator is properly configured +func (r *RelayAddressGeneratorPortRange) Validate() error { + if r.Net == nil { + r.Net = vnet.NewNet(nil) + } + + if r.Rand == nil { + r.Rand = randutil.NewMathRandomGenerator() + } + + if r.MaxRetries == 0 { + r.MaxRetries = 10 + } + + switch { + case r.MinPort == 0: + return errMinPortNotZero + case r.MaxPort == 0: + return errMaxPortNotZero + case r.RelayAddress == nil: + return errRelayAddressInvalid + case r.Address == "": + return errListeningAddressInvalid + default: + return nil + } +} + +// AllocatePacketConn generates a new PacketConn to receive traffic on and the IP/Port to populate the allocation response with +func (r *RelayAddressGeneratorPortRange) AllocatePacketConn(network string, requestedPort int) (net.PacketConn, net.Addr, error) { + if requestedPort != 0 { + conn, err := r.Net.ListenPacket(network, fmt.Sprintf("%s:%d", r.Address, requestedPort)) + if err != nil { + return nil, nil, err + } + relayAddr := conn.LocalAddr().(*net.UDPAddr) + relayAddr.IP = r.RelayAddress + return conn, relayAddr, nil + } + + for try := 0; try < r.MaxRetries; try++ { + port := r.MinPort + uint16(r.Rand.Intn(int((r.MaxPort+1)-r.MinPort))) + conn, err := r.Net.ListenPacket(network, fmt.Sprintf("%s:%d", r.Address, port)) + if err != nil { + continue + } + + relayAddr := conn.LocalAddr().(*net.UDPAddr) + relayAddr.IP = r.RelayAddress + return conn, relayAddr, nil + } + + return nil, nil, errMaxRetriesExceeded +} + +// AllocateConn generates a new Conn to receive traffic on and the IP/Port to populate the allocation response with +func (r *RelayAddressGeneratorPortRange) AllocateConn(network string, requestedPort int) (net.Conn, net.Addr, error) { + return nil, nil, errTODO +} |