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

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