github.com/sagernet/sing-box@v1.9.0-rc.20/transport/v2raygrpc/conn.go (about)

     1  package v2raygrpc
     2  
     3  import (
     4  	"net"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/sagernet/sing/common"
     9  	"github.com/sagernet/sing/common/baderror"
    10  	M "github.com/sagernet/sing/common/metadata"
    11  	"github.com/sagernet/sing/common/rw"
    12  )
    13  
    14  var _ net.Conn = (*GRPCConn)(nil)
    15  
    16  type GRPCConn struct {
    17  	GunService
    18  	cancel common.ContextCancelCauseFunc
    19  	cache  []byte
    20  }
    21  
    22  func NewGRPCConn(service GunService, cancel common.ContextCancelCauseFunc) *GRPCConn {
    23  	if client, isClient := service.(GunService_TunClient); isClient {
    24  		service = &clientConnWrapper{client}
    25  	}
    26  	return &GRPCConn{
    27  		GunService: service,
    28  		cancel:     cancel,
    29  	}
    30  }
    31  
    32  func (c *GRPCConn) Read(b []byte) (n int, err error) {
    33  	if len(c.cache) > 0 {
    34  		n = copy(b, c.cache)
    35  		c.cache = c.cache[n:]
    36  		return
    37  	}
    38  	hunk, err := c.Recv()
    39  	err = baderror.WrapGRPC(err)
    40  	if err != nil {
    41  		c.cancel(err)
    42  		return
    43  	}
    44  	n = copy(b, hunk.Data)
    45  	if n < len(hunk.Data) {
    46  		c.cache = hunk.Data[n:]
    47  	}
    48  	return
    49  }
    50  
    51  func (c *GRPCConn) Write(b []byte) (n int, err error) {
    52  	err = baderror.WrapGRPC(c.Send(&Hunk{Data: b}))
    53  	if err != nil {
    54  		c.cancel(err)
    55  		return
    56  	}
    57  	return len(b), nil
    58  }
    59  
    60  func (c *GRPCConn) Close() error {
    61  	c.cancel(net.ErrClosed)
    62  	return nil
    63  }
    64  
    65  func (c *GRPCConn) LocalAddr() net.Addr {
    66  	return M.Socksaddr{}
    67  }
    68  
    69  func (c *GRPCConn) RemoteAddr() net.Addr {
    70  	return M.Socksaddr{}
    71  }
    72  
    73  func (c *GRPCConn) SetDeadline(t time.Time) error {
    74  	return os.ErrInvalid
    75  }
    76  
    77  func (c *GRPCConn) SetReadDeadline(t time.Time) error {
    78  	return os.ErrInvalid
    79  }
    80  
    81  func (c *GRPCConn) SetWriteDeadline(t time.Time) error {
    82  	return os.ErrInvalid
    83  }
    84  
    85  func (c *GRPCConn) NeedAdditionalReadDeadline() bool {
    86  	return true
    87  }
    88  
    89  func (c *GRPCConn) Upstream() any {
    90  	return c.GunService
    91  }
    92  
    93  var _ rw.WriteCloser = (*clientConnWrapper)(nil)
    94  
    95  type clientConnWrapper struct {
    96  	GunService_TunClient
    97  }
    98  
    99  func (c *clientConnWrapper) CloseWrite() error {
   100  	return c.CloseSend()
   101  }