/
grpc.go
115 lines (95 loc) · 2.08 KB
/
grpc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package tunnel
import (
"context"
"errors"
"fmt"
"net"
"time"
"google.golang.org/grpc"
pb "github.com/DVKunion/SeaMoon/pkg/proto"
)
type grpcConn struct {
cc grpc.Stream
rb []byte
lAddr net.Addr
rAddr net.Addr
}
func GRPCWrapConn(addr net.Addr, cc grpc.Stream) Tunnel {
return &grpcConn{
cc: cc,
lAddr: addr,
rAddr: &net.TCPAddr{},
}
}
func (c *grpcConn) Read(b []byte) (n int, err error) {
if len(c.rb) == 0 {
chunk, err := c.recv()
if err != nil {
return 0, err
}
c.rb = chunk.Body
}
n = copy(b, c.rb)
c.rb = c.rb[n:]
return
}
func (c *grpcConn) Write(b []byte) (n int, err error) {
chunk := &pb.Chunk{
Body: b,
Size: int32(len(b)),
}
if err = c.send(chunk); err != nil {
return
}
n = int(chunk.Size)
return
}
func (c *grpcConn) Close() error {
switch cost := c.cc.(type) {
case pb.Tunnel_HttpClient:
case pb.Tunnel_Socks5Client:
return cost.CloseSend()
}
return nil
}
func (c *grpcConn) LocalAddr() net.Addr {
return c.lAddr
}
func (c *grpcConn) RemoteAddr() net.Addr {
return c.rAddr
}
func (c *grpcConn) SetDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *grpcConn) SetReadDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *grpcConn) SetWriteDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "grpc", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *grpcConn) context() context.Context {
if c.cc != nil {
return c.cc.Context()
}
return context.Background()
}
func (c *grpcConn) send(data *pb.Chunk) error {
sender, ok := c.cc.(interface {
Send(*pb.Chunk) error
})
if !ok {
// todo
return fmt.Errorf("unsupported type: %T", c.cc)
}
return sender.Send(data)
}
func (c *grpcConn) recv() (*pb.Chunk, error) {
receiver, ok := c.cc.(interface {
Recv() (*pb.Chunk, error)
})
if !ok {
// todo
return nil, fmt.Errorf("unsupported type: %T", c.cc)
}
return receiver.Recv()
}