github.com/ipfans/trojan-go@v0.11.0/tunnel/tproxy/conn.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package tproxy
     5  
     6  import (
     7  	"context"
     8  	"net"
     9  
    10  	"github.com/ipfans/trojan-go/common"
    11  	"github.com/ipfans/trojan-go/tunnel"
    12  )
    13  
    14  type Conn struct {
    15  	net.Conn
    16  	metadata *tunnel.Metadata
    17  }
    18  
    19  func (c *Conn) Metadata() *tunnel.Metadata {
    20  	return c.metadata
    21  }
    22  
    23  type packetInfo struct {
    24  	metadata *tunnel.Metadata
    25  	payload  []byte
    26  }
    27  
    28  type PacketConn struct {
    29  	net.PacketConn
    30  	input  chan *packetInfo
    31  	output chan *packetInfo
    32  	src    net.Addr
    33  	ctx    context.Context
    34  	cancel context.CancelFunc
    35  }
    36  
    37  func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
    38  	panic("implement me")
    39  }
    40  
    41  func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
    42  	panic("implement me")
    43  }
    44  
    45  func (c *PacketConn) Close() error {
    46  	c.cancel()
    47  	return nil
    48  }
    49  
    50  func (c *PacketConn) WriteWithMetadata(p []byte, m *tunnel.Metadata) (int, error) {
    51  	select {
    52  	case c.output <- &packetInfo{
    53  		metadata: m,
    54  		payload:  p,
    55  	}:
    56  		return len(p), nil
    57  	case <-c.ctx.Done():
    58  		return 0, common.NewError("socks packet conn closed")
    59  	}
    60  }
    61  
    62  func (c *PacketConn) ReadWithMetadata(p []byte) (int, *tunnel.Metadata, error) {
    63  	select {
    64  	case info := <-c.input:
    65  		n := copy(p, info.payload)
    66  		return n, info.metadata, nil
    67  	case <-c.ctx.Done():
    68  		return 0, nil, common.NewError("socks packet conn closed")
    69  	}
    70  }