github.com/metacubex/mihomo@v1.18.5/transport/hysteria/conns/udp/obfs.go (about)

     1  package udp
     2  
     3  import (
     4  	"github.com/metacubex/mihomo/transport/hysteria/obfs"
     5  	"net"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  const udpBufferSize = 65535
    11  
    12  type ObfsUDPConn struct {
    13  	orig       net.PacketConn
    14  	obfs       obfs.Obfuscator
    15  	readBuf    []byte
    16  	readMutex  sync.Mutex
    17  	writeBuf   []byte
    18  	writeMutex sync.Mutex
    19  }
    20  
    21  func NewObfsUDPConn(orig net.PacketConn, obfs obfs.Obfuscator) *ObfsUDPConn {
    22  	return &ObfsUDPConn{
    23  		orig:     orig,
    24  		obfs:     obfs,
    25  		readBuf:  make([]byte, udpBufferSize),
    26  		writeBuf: make([]byte, udpBufferSize),
    27  	}
    28  }
    29  
    30  func (c *ObfsUDPConn) ReadFrom(p []byte) (int, net.Addr, error) {
    31  	for {
    32  		c.readMutex.Lock()
    33  		n, addr, err := c.orig.ReadFrom(c.readBuf)
    34  		if n <= 0 {
    35  			c.readMutex.Unlock()
    36  			return 0, addr, err
    37  		}
    38  		newN := c.obfs.Deobfuscate(c.readBuf[:n], p)
    39  		c.readMutex.Unlock()
    40  		if newN > 0 {
    41  			// Valid packet
    42  			return newN, addr, err
    43  		} else if err != nil {
    44  			// Not valid and orig.ReadFrom had some error
    45  			return 0, addr, err
    46  		}
    47  	}
    48  }
    49  
    50  func (c *ObfsUDPConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
    51  	c.writeMutex.Lock()
    52  	bn := c.obfs.Obfuscate(p, c.writeBuf)
    53  	_, err = c.orig.WriteTo(c.writeBuf[:bn], addr)
    54  	c.writeMutex.Unlock()
    55  	if err != nil {
    56  		return 0, err
    57  	} else {
    58  		return len(p), nil
    59  	}
    60  }
    61  
    62  func (c *ObfsUDPConn) Close() error {
    63  	return c.orig.Close()
    64  }
    65  
    66  func (c *ObfsUDPConn) LocalAddr() net.Addr {
    67  	return c.orig.LocalAddr()
    68  }
    69  
    70  func (c *ObfsUDPConn) SetDeadline(t time.Time) error {
    71  	return c.orig.SetDeadline(t)
    72  }
    73  
    74  func (c *ObfsUDPConn) SetReadDeadline(t time.Time) error {
    75  	return c.orig.SetReadDeadline(t)
    76  }
    77  
    78  func (c *ObfsUDPConn) SetWriteDeadline(t time.Time) error {
    79  	return c.orig.SetWriteDeadline(t)
    80  }