@@ -2,20 +2,18 @@ package portfwd
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"fmt"
7
- "io"
8
6
"net"
7
+ "time"
9
8
9
+ "github.com/containers/gvisor-tap-vsock/pkg/services/forwarder"
10
+ "github.com/lima-vm/lima/pkg/bicopy"
10
11
"github.com/lima-vm/lima/pkg/guestagent/api"
11
12
guestagentclient "github.com/lima-vm/lima/pkg/guestagent/api/client"
12
13
"github.com/sirupsen/logrus"
13
- "golang.org/x/sync/errgroup"
14
14
)
15
15
16
16
func HandleTCPConnection (ctx context.Context , client * guestagentclient.GuestAgentClient , conn net.Conn , guestAddr string ) {
17
- defer conn .Close ()
18
-
19
17
id := fmt .Sprintf ("tcp-%s-%s" , conn .LocalAddr ().String (), conn .RemoteAddr ().String ())
20
18
21
19
stream , err := client .Tunnel (ctx )
@@ -24,26 +22,17 @@ func HandleTCPConnection(ctx context.Context, client *guestagentclient.GuestAgen
24
22
return
25
23
}
26
24
27
- g , _ := errgroup .WithContext (ctx )
28
-
29
- rw := & GrpcClientRW {stream : stream , id : id , addr : guestAddr }
30
- g .Go (func () error {
31
- _ , err := io .Copy (rw , conn )
32
- return err
33
- })
34
- g .Go (func () error {
35
- _ , err := io .Copy (conn , rw )
36
- return err
37
- })
38
-
39
- if err := g .Wait (); err != nil {
40
- logrus .Debugf ("error in tcp tunnel for id: %s error:%v" , id , err )
25
+ // Handshake message to start tunnel
26
+ if err := stream .Send (& api.TunnelMessage {Id : id , Protocol : "tcp" , GuestAddr : guestAddr }); err != nil {
27
+ logrus .Errorf ("could not start tcp tunnel for id: %s error:%v" , id , err )
28
+ return
41
29
}
30
+
31
+ rw := & GrpcClientRW {stream : stream , id : id , addr : guestAddr , protocol : "tcp" }
32
+ bicopy .Bicopy (rw , conn , nil )
42
33
}
43
34
44
35
func HandleUDPConnection (ctx context.Context , client * guestagentclient.GuestAgentClient , conn net.PacketConn , guestAddr string ) {
45
- defer conn .Close ()
46
-
47
36
id := fmt .Sprintf ("udp-%s" , conn .LocalAddr ().String ())
48
37
49
38
stream , err := client .Tunnel (ctx )
@@ -52,98 +41,82 @@ func HandleUDPConnection(ctx context.Context, client *guestagentclient.GuestAgen
52
41
return
53
42
}
54
43
55
- g , _ := errgroup .WithContext (ctx )
56
-
57
- g .Go (func () error {
58
- buf := make ([]byte , 65507 )
59
- for {
60
- n , addr , err := conn .ReadFrom (buf )
61
- // We must handle n > 0 bytes before considering the error.
62
- // https://pkg.go.dev/net#PacketConn
63
- if n > 0 {
64
- msg := & api.TunnelMessage {
65
- Id : id + "-" + addr .String (),
66
- Protocol : "udp" ,
67
- GuestAddr : guestAddr ,
68
- Data : buf [:n ],
69
- UdpTargetAddr : addr .String (),
70
- }
71
- if err := stream .Send (msg ); err != nil {
72
- return err
73
- }
74
- }
75
- if err != nil {
76
- // https://pkg.go.dev/net#PacketConn does not mention io.EOF semantics.
77
- if errors .Is (err , io .EOF ) {
78
- return nil
79
- }
80
- return err
81
- }
82
- }
83
- })
44
+ // Handshake message to start tunnel
45
+ if err := stream .Send (& api.TunnelMessage {Id : id , Protocol : "udp" , GuestAddr : guestAddr }); err != nil {
46
+ logrus .Errorf ("could not start udp tunnel for id: %s error:%v" , id , err )
47
+ return
48
+ }
84
49
85
- g .Go (func () error {
86
- for {
87
- // Not documented: when err != nil, in is always nil.
88
- in , err := stream .Recv ()
89
- if err != nil {
90
- if errors .Is (err , io .EOF ) {
91
- return nil
92
- }
93
- return err
94
- }
95
- addr , err := net .ResolveUDPAddr ("udp" , in .UdpTargetAddr )
96
- if err != nil {
97
- return err
98
- }
99
- _ , err = conn .WriteTo (in .Data , addr )
100
- if err != nil {
101
- return err
102
- }
103
- }
50
+ proxy , err := forwarder .NewUDPProxy (conn , func () (net.Conn , error ) {
51
+ rw := & GrpcClientRW {stream : stream , id : id , addr : guestAddr , protocol : "udp" }
52
+ return rw , nil
104
53
})
105
-
106
- if err := g . Wait (); err != nil {
107
- logrus . Debugf ( "error in udp tunnel for id: %s error:%v" , id , err )
54
+ if err != nil {
55
+ logrus . Errorf ( "error in udp tunnel proxy for id: %s error:%v" , id , err )
56
+ return
108
57
}
58
+
59
+ defer func () {
60
+ err := proxy .Close ()
61
+ if err != nil {
62
+ logrus .Errorf ("error in closing udp tunnel proxy for id: %s error:%v" , id , err )
63
+ }
64
+ }()
65
+ proxy .Run ()
109
66
}
110
67
111
68
type GrpcClientRW struct {
112
- id string
113
- addr string
114
- stream api.GuestService_TunnelClient
69
+ id string
70
+ addr string
71
+
72
+ protocol string
73
+ stream api.GuestService_TunnelClient
115
74
}
116
75
117
- var _ io. ReadWriter = (* GrpcClientRW )(nil )
76
+ var _ net. Conn = (* GrpcClientRW )(nil )
118
77
119
- func (g GrpcClientRW ) Write (p []byte ) (n int , err error ) {
120
- if len (p ) == 0 {
121
- return 0 , nil
122
- }
78
+ func (g * GrpcClientRW ) Write (p []byte ) (n int , err error ) {
123
79
err = g .stream .Send (& api.TunnelMessage {
124
80
Id : g .id ,
125
81
GuestAddr : g .addr ,
126
82
Data : p ,
127
- Protocol : "tcp" ,
83
+ Protocol : g . protocol ,
128
84
})
129
85
if err != nil {
130
86
return 0 , err
131
87
}
132
88
return len (p ), nil
133
89
}
134
90
135
- func (g GrpcClientRW ) Read (p []byte ) (n int , err error ) {
136
- // Not documented: when err != nil, in is always nil.
91
+ func (g * GrpcClientRW ) Read (p []byte ) (n int , err error ) {
137
92
in , err := g .stream .Recv ()
138
93
if err != nil {
139
- if errors .Is (err , io .EOF ) {
140
- return 0 , nil
141
- }
142
94
return 0 , err
143
95
}
144
- if len (in .Data ) == 0 {
145
- return 0 , nil
146
- }
147
96
copy (p , in .Data )
148
97
return len (in .Data ), nil
149
98
}
99
+
100
+ func (g * GrpcClientRW ) Close () error {
101
+ return g .stream .CloseSend ()
102
+ }
103
+
104
+ func (g * GrpcClientRW ) LocalAddr () net.Addr {
105
+ return & net.UnixAddr {Name : "grpc" , Net : "unixpacket" }
106
+ }
107
+
108
+ func (g * GrpcClientRW ) RemoteAddr () net.Addr {
109
+ return & net.UnixAddr {Name : "grpc" , Net : "unixpacket" }
110
+ }
111
+
112
+ func (g * GrpcClientRW ) SetDeadline (_ time.Time ) error {
113
+ return nil
114
+ }
115
+
116
+ func (g * GrpcClientRW ) SetReadDeadline (_ time.Time ) error {
117
+ return nil
118
+ }
119
+
120
+ func (g * GrpcClientRW ) SetWriteDeadline (_ time.Time ) error {
121
+ return nil
122
+ }
0 commit comments