mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 14:47:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package udpmux
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"errors"
 | 
						|
	"net"
 | 
						|
	"time"
 | 
						|
 | 
						|
	pool "github.com/libp2p/go-buffer-pool"
 | 
						|
)
 | 
						|
 | 
						|
type packet struct {
 | 
						|
	buf  []byte
 | 
						|
	addr net.Addr
 | 
						|
}
 | 
						|
 | 
						|
var _ net.PacketConn = &muxedConnection{}
 | 
						|
 | 
						|
const queueLen = 128
 | 
						|
 | 
						|
// muxedConnection provides a net.PacketConn abstraction
 | 
						|
// over packetQueue and adds the ability to store addresses
 | 
						|
// from which this connection (indexed by ufrag) received
 | 
						|
// data.
 | 
						|
type muxedConnection struct {
 | 
						|
	ctx     context.Context
 | 
						|
	cancel  context.CancelFunc
 | 
						|
	onClose func()
 | 
						|
	queue   chan packet
 | 
						|
	mux     *UDPMux
 | 
						|
}
 | 
						|
 | 
						|
var _ net.PacketConn = &muxedConnection{}
 | 
						|
 | 
						|
func newMuxedConnection(mux *UDPMux, onClose func()) *muxedConnection {
 | 
						|
	ctx, cancel := context.WithCancel(mux.ctx)
 | 
						|
	return &muxedConnection{
 | 
						|
		ctx:     ctx,
 | 
						|
		cancel:  cancel,
 | 
						|
		queue:   make(chan packet, queueLen),
 | 
						|
		onClose: onClose,
 | 
						|
		mux:     mux,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *muxedConnection) Push(buf []byte, addr net.Addr) error {
 | 
						|
	select {
 | 
						|
	case <-c.ctx.Done():
 | 
						|
		return errors.New("closed")
 | 
						|
	default:
 | 
						|
	}
 | 
						|
	select {
 | 
						|
	case c.queue <- packet{buf: buf, addr: addr}:
 | 
						|
		return nil
 | 
						|
	default:
 | 
						|
		return errors.New("queue full")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *muxedConnection) ReadFrom(buf []byte) (int, net.Addr, error) {
 | 
						|
	select {
 | 
						|
	case p := <-c.queue:
 | 
						|
		n := copy(buf, p.buf) // This might discard parts of the packet, if p is too short
 | 
						|
		if n < len(p.buf) {
 | 
						|
			log.Debugf("short read, had %d, read %d", len(p.buf), n)
 | 
						|
		}
 | 
						|
		pool.Put(p.buf)
 | 
						|
		return n, p.addr, nil
 | 
						|
	case <-c.ctx.Done():
 | 
						|
		return 0, nil, c.ctx.Err()
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *muxedConnection) WriteTo(p []byte, addr net.Addr) (n int, err error) {
 | 
						|
	return c.mux.writeTo(p, addr)
 | 
						|
}
 | 
						|
 | 
						|
func (c *muxedConnection) Close() error {
 | 
						|
	select {
 | 
						|
	case <-c.ctx.Done():
 | 
						|
		return nil
 | 
						|
	default:
 | 
						|
	}
 | 
						|
	c.onClose()
 | 
						|
	c.cancel()
 | 
						|
	// drain the packet queue
 | 
						|
	for {
 | 
						|
		select {
 | 
						|
		case p := <-c.queue:
 | 
						|
			pool.Put(p.buf)
 | 
						|
		default:
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *muxedConnection) LocalAddr() net.Addr { return c.mux.socket.LocalAddr() }
 | 
						|
 | 
						|
func (*muxedConnection) SetDeadline(t time.Time) error {
 | 
						|
	// no deadline is desired here
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (*muxedConnection) SetReadDeadline(t time.Time) error {
 | 
						|
	// no read deadline is desired here
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (*muxedConnection) SetWriteDeadline(t time.Time) error {
 | 
						|
	// no write deadline is desired here
 | 
						|
	return nil
 | 
						|
}
 |