func (s *STUNConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
	return s.nextConn.Write(p)
}
WriteTo implements WriteTo from net.PacketConn
package turn
import (
	"encoding/binary"
	"errors"
	"net"
	"time"
	"github.com/pion/stun"
	"github.com/pion/turn/v2/internal/proto"
)
var (
	errInvalidTURNFrame    = errors.New("data is not a valid TURN frame, no STUN or ChannelData found")
	errIncompleteTURNFrame = errors.New("data contains incomplete STUN or TURN frame")
)
type STUNConn struct {
	nextConn net.Conn
	buff     []byte
}
const (
	stunHeaderSize = 20
	channelDataLengthSize = 2
	channelDataNumberSize = channelDataLengthSize
	channelDataHeaderSize = channelDataLengthSize + channelDataNumberSize
	channelDataPadding    = 4
)
func consumeSingleTURNFrame(p []byte) (int, error) {
	if len(p) < 9 {
		return 0, errIncompleteTURNFrame
	}
	var datagramSize uint16
	if stun.IsMessage(p) {
		datagramSize = binary.BigEndian.Uint16(p[2:4]) + stunHeaderSize
	} else if num := binary.BigEndian.Uint16(p[0:4]); proto.ChannelNumber(num).Valid() {
		datagramSize = binary.BigEndian.Uint16(p[channelDataNumberSize:channelDataHeaderSize])
		if paddingOverflow := (datagramSize + channelDataPadding) % channelDataPadding; paddingOverflow != 0 {
			datagramSize = (datagramSize + channelDataPadding) - paddingOverflow
		}
		datagramSize += channelDataHeaderSize
	} else {
		return 0, errInvalidTURNFrame
	}
	if len(p) < int(datagramSize) {
		return 0, errIncompleteTURNFrame
	}
	return int(datagramSize), nil
}
func (s *STUNConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
	n, err = consumeSingleTURNFrame(s.buff)
	if errors.Is(err, errInvalidTURNFrame) {
		return 0, nil, err
	} else if err == nil {
		copy(p, s.buff[:n])
		s.buff = s.buff[n:]
		return n, s.nextConn.RemoteAddr(), nil
	}
	n, err = s.nextConn.Read(p)
	if err != nil {
		return 0, nil, err
	}
	s.buff = append(s.buff, append([]byte{}, p[:n]...)...)
	return s.ReadFrom(p)
}