func NewSocketFromPacketConn(pc net.PacketConn) (s *Socket, err error) {
	s = &Socket{
		backlog: make(map[syn]struct{}, backlog),
		reads:   make(chan read, 100),
		pc:      pc,
		unusedReads: make(chan read, 100),
	}
	mu.Lock()
	sockets[s] = struct{}{}
	mu.Unlock()
	go s.reader()
	go s.dispatcher()
	return
}
Create a Socket, using the provided net.PacketConn. If you want to retain
use of the net.PacketConn after the Socket closes it, override your
net.PacketConn's Close method.
package utp
import (
	"encoding/binary"
	"errors"
	"expvar"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net"
	"os"
	"strconv"
	"sync"
	"time"
	"github.com/anacrolix/missinggo"
	"github.com/anacrolix/missinggo/pproffd"
)
const (
	backlog = 50
	minMTU     = 1232
	recvWindow = 1 << 18  
	maxHeaderSize  = 30
	maxPayloadSize = minMTU - maxHeaderSize
	maxRecvSize    = 0x2000
	maxUnackedInbound = 256
	maxUnackedSends   = 256
)
var (
	ackSkippedResends = expvar.NewInt("utpAckSkippedResends")
	deliveriesProcessed = expvar.NewInt("utpDeliveriesProcessed")
	sentStatePackets    = expvar.NewInt("utpSentStatePackets")
	unusedReads         = expvar.NewInt("utpUnusedReads")
	sendBufferPool      = sync.Pool{
		New: func() interface{} { return make([]byte, minMTU) },
	}
	initialLatency = 400 * time.Millisecond
	writeTimeout      = 15 * time.Second
	packetReadTimeout = 2 * time.Minute
)
type deadlineCallback struct {
	deadline time.Time
	timer    *time.Timer
	callback func()
}
func (me *deadlineCallback) deadlineExceeded() bool {
	return !me.deadline.IsZero() && !time.Now().Before(me.deadline)
}
func (me *deadlineCallback) updateTimer() {
	if me.timer != nil {
		me.timer.Stop()
	}
	if me.deadline.IsZero() {
		return
	}
	if me.callback == nil {
		panic("deadline callback is nil")
	}
	me.timer = time.AfterFunc(me.deadline.Sub(time.Now()), me.callback)
}
func (me *deadlineCallback) setDeadline(t time.Time) {
	me.deadline = t
	me.updateTimer()
}
func (me *deadlineCallback) setCallback(f func()) {
	me.callback = f
	me.updateTimer()
}
type connDeadlines struct {
	read, write deadlineCallback
}
func (c *connDeadlines) SetDeadline(t time.Time) error {
	c.read.setDeadline(t)
	c.write.setDeadline(t)
	return nil
}
func (c *connDeadlines) SetReadDeadline(t time.Time) error {
	c.read.setDeadline(t)
	return nil
}
func (c *connDeadlines) SetWriteDeadline(t time.Time) error {
	c.write.setDeadline(t)
	return nil
}
type resolvedAddrStr string
type connKey struct {
	remoteAddr resolvedAddrStr
	connID     uint16
}
type Socket struct {
	mu    sync.RWMutex
	pc    net.PacketConn
	conns map[connKey]*Conn
	backlogNotEmpty missinggo.Event
	backlog         map[syn]struct{}
	reads  chan read
	closed missinggo.Event
	unusedReads chan read
	connDeadlines
	ReadErr error
}
type read struct {
	data []byte
	from net.Addr
}
type syn struct {
	seq_nr, conn_id uint16
	addr            string
}
const (
	extensionTypeSelectiveAck = 1
)
type extensionField struct {
	Type  byte
	Bytes []byte
}
type header struct {
	Type          st
	Version       int
	ConnID        uint16
	Timestamp     uint32
	TimestampDiff uint32
	WndSize       uint32
	SeqNr         uint16
	AckNr         uint16
	Extensions    []extensionField
}
var (
	mu                         sync.RWMutex
	sockets                    = map[*Socket]struct{}{}
	logLevel                   = 0
	artificialPacketDropChance = 0.0
)
func init() {
	logLevel, _ = strconv.Atoi(os.Getenv("GO_UTP_LOGGING"))
	fmt.Sscanf(os.Getenv("GO_UTP_PACKET_DROP"), "%f", &artificialPacketDropChance)
}
var (
	errClosed                   = errors.New("closed")
	errNotImplemented           = errors.New("not implemented")
	errTimeout        net.Error = timeoutError{"i/o timeout"}
	errAckTimeout               = timeoutError{"timed out waiting for ack"}
)
type timeoutError struct {
	msg string
}
func (me timeoutError) Timeout() bool   { return true }
func (me timeoutError) Error() string   { return me.msg }
func (me timeoutError) Temporary() bool { return false }
func unmarshalExtensions(_type byte, b []byte) (n int, ef []extensionField, err error) {
	for _type != 0 {
		if _type != extensionTypeSelectiveAck {
		}
		if len(b) < 2 || len(b) < int(b[1])+2 {
			err = fmt.Errorf("buffer ends prematurely: %x", b)
			return
		}
		ef = append(ef, extensionField{
			Type:  _type,
			Bytes: append([]byte{}, b[2:int(b[1])+2]...),
		})
		_type = b[0]
		n += 2 + int(b[1])
		b = b[2+int(b[1]):]
	}
	return
}
var errInvalidHeader = errors.New("invalid header")
func (h *header) Unmarshal(b []byte) (n int, err error) {
	h.Type = st(b[0] >> 4)
	h.Version = int(b[0] & 0xf)
	if h.Type > stMax || h.Version != 1 {
		err = errInvalidHeader
		return
	}
	n, h.Extensions, err = unmarshalExtensions(b[1], b[20:])
	if err != nil {
		return
	}
	h.ConnID = binary.BigEndian.Uint16(b[2:4])
	h.Timestamp = binary.BigEndian.Uint32(b[4:8])
	h.TimestampDiff = binary.BigEndian.Uint32(b[8:12])
	h.WndSize = binary.BigEndian.Uint32(b[12:16])
	h.SeqNr = binary.BigEndian.Uint16(b[16:18])
	h.AckNr = binary.BigEndian.Uint16(b[18:20])
	n += 20
	return
}
func (h *header) Marshal() (ret []byte) {
	hLen := 20 + func() (ret int) {
		for _, ext := range h.Extensions {
			ret += 2 + len(ext.Bytes)
		}
		return
	}()
	ret = sendBufferPool.Get().([]byte)[:hLen:minMTU]
	p := ret  
	p[0] = byte(h.Type<<4 | 1)
	binary.BigEndian.PutUint16(p[2:4], h.ConnID)
	binary.BigEndian.PutUint32(p[4:8], h.Timestamp)
	binary.BigEndian.PutUint32(p[8:12], h.TimestampDiff)
	binary.BigEndian.PutUint32(p[12:16], h.WndSize)
	binary.BigEndian.PutUint16(p[16:18], h.SeqNr)
	binary.BigEndian.PutUint16(p[18:20], h.AckNr)
	_type := &p[1]
	p = p[20:]
	for _, ext := range h.Extensions {
		*_type = ext.Type
		_type = &p[0]
		p[1] = uint8(len(ext.Bytes))
		if int(p[1]) != copy(p[2:], ext.Bytes) {
			panic("unexpected extension length")
		}
		p = p[2+len(ext.Bytes):]
	}
	if len(p) != 0 {
		panic("header length changed")
	}
	return
}
var (
	_ net.Listener   = &Socket{}
	_ net.PacketConn = &Socket{}
)
type st int
func (me st) String() string {
	switch me {
	case stData:
		return "stData"
	case stFin:
		return "stFin"
	case stState:
		return "stState"
	case stReset:
		return "stReset"
	case stSyn:
		return "stSyn"
	default:
		panic(fmt.Sprintf("%d", me))
	}
}
const (
	stData  st = 0
	stFin      = 1
	stState    = 2
	stReset    = 3
	stSyn      = 4
	stMax = stSyn
)
type Conn struct {
	mu    sync.Mutex
	event sync.Cond
	recv_id, send_id uint16
	seq_nr, ack_nr   uint16
	lastAck          uint16
	lastTimeDiff     uint32
	peerWndSize      uint32
	cur_window       uint32
	readBuf []byte
	socket     *Socket
	remoteAddr net.Addr
	startTimestamp uint32
	created time.Time
	sentSyn  bool
	synAcked bool
	gotFin   bool
	wroteFin bool
	finAcked bool
	err      error
	closing  bool
	closed   bool
	unackedSends []*send
	inbound    []recv
	inboundWnd uint32
	packetsIn  chan packet
	connDeadlines
	latencies        []time.Duration
	pendingSendState bool
}
type send struct {
	acked       bool  
	payloadSize uint32
	started     missinggo.MonotonicTime
	resend   func()
	timedOut func()
	conn     *Conn
	acksSkipped int
	resendTimer *time.Timer
	numResends  int
}
func (s *send) Ack() (latency time.Duration, first bool) {
	s.resendTimer.Stop()
	if s.acked {
		return
	}
	s.acked = true
	s.conn.event.Broadcast()
	first = true
	latency = missinggo.MonotonicSince(s.started)
	return
}
type recv struct {
	seen bool
	data []byte
	Type st
}
var (
	_ net.Conn = &Conn{}
)
func (c *Conn) age() time.Duration {
	return time.Since(c.created)
}
func (c *Conn) timestamp() uint32 {
	return nowTimestamp() - c.startTimestamp
}