github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/dialer/conntrack/packet_conn.go (about)

     1  package conntrack
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  
     7  	"github.com/sagernet/sing/common/bufio"
     8  	"github.com/sagernet/sing/common/x/list"
     9  )
    10  
    11  type PacketConn struct {
    12  	net.PacketConn
    13  	element *list.Element[io.Closer]
    14  }
    15  
    16  func NewPacketConn(conn net.PacketConn) (net.PacketConn, error) {
    17  	connAccess.Lock()
    18  	element := openConnection.PushBack(conn)
    19  	connAccess.Unlock()
    20  	if KillerEnabled {
    21  		err := killerCheck()
    22  		if err != nil {
    23  			conn.Close()
    24  			return nil, err
    25  		}
    26  	}
    27  	return &PacketConn{
    28  		PacketConn: conn,
    29  		element:    element,
    30  	}, nil
    31  }
    32  
    33  func (c *PacketConn) Close() error {
    34  	if c.element.Value != nil {
    35  		connAccess.Lock()
    36  		if c.element.Value != nil {
    37  			openConnection.Remove(c.element)
    38  			c.element.Value = nil
    39  		}
    40  		connAccess.Unlock()
    41  	}
    42  	return c.PacketConn.Close()
    43  }
    44  
    45  func (c *PacketConn) Upstream() any {
    46  	return bufio.NewPacketConn(c.PacketConn)
    47  }
    48  
    49  func (c *PacketConn) ReaderReplaceable() bool {
    50  	return true
    51  }
    52  
    53  func (c *PacketConn) WriterReplaceable() bool {
    54  	return true
    55  }