@@ -8,13 +8,11 @@ import (
88 "errors"
99 "io"
1010 "net"
11- "os"
12- "strings"
1311 "time"
1412
1513 "github.com/containers/gvisor-tap-vsock/pkg/tcpproxy"
14+ "github.com/sirupsen/logrus"
1615
17- "github.com/lima-vm/lima/v2/pkg/bicopy"
1816 "github.com/lima-vm/lima/v2/pkg/guestagent/api"
1917)
2018
@@ -41,30 +39,30 @@ func (s *TunnelServer) Start(stream api.GuestService_TunnelServer) error {
4139 if err != nil {
4240 return err
4341 }
44- rw := & GRPCServerRW {stream : stream , id : in .Id }
45-
46- // FIXME: consolidate bicopy and tcpproxy into one
47- //
48- // The bicopy package does not seem to work with `w3m -dump`:
49- // https://github.com/lima-vm/lima/issues/3685
50- //
51- // However, the tcpproxy package can't pass the CI for WSL2 (experimental):
52- // https://github.com/lima-vm/lima/pull/3686#issuecomment-3034842616
53- if wsl2 , _ := seemsWSL2 (); wsl2 {
54- bicopy .Bicopy (rw , conn , nil )
55- } else {
56- proxy := tcpproxy.DialProxy {DialContext : func (_ context.Context , _ , _ string ) (net.Conn , error ) {
57- return conn , nil
58- }}
59- proxy .HandleConn (rw )
60- }
42+ rw := & GRPCServerRW {stream : stream , id : in .Id , closeCh : make (chan any , 1 )}
43+ go func () {
44+ <- ctx .Done ()
45+ rw .Close ()
46+ }()
47+
48+ proxy := tcpproxy.DialProxy {DialContext : func (_ context.Context , _ , _ string ) (net.Conn , error ) {
49+ return conn , nil
50+ }}
51+ go proxy .HandleConn (rw )
52+
53+ // The stream will be closed when this function returns.
54+ // Wait here until rw.Close(), rw.CloseRead(), or rw.CloseWrite() is called.
55+ // We can't close rw.closeCh since the calling order of Close* methods is not guaranteed.
56+ <- rw .closeCh
57+ logrus .Debugf ("closed GRPCServerRW for id: %s" , in .Id )
6158
6259 return nil
6360}
6461
6562type GRPCServerRW struct {
66- id string
67- stream api.GuestService_TunnelServer
63+ id string
64+ stream api.GuestService_TunnelServer
65+ closeCh chan any
6866}
6967
7068var _ net.Conn = (* GRPCServerRW )(nil )
@@ -84,6 +82,23 @@ func (g *GRPCServerRW) Read(p []byte) (n int, err error) {
8482}
8583
8684func (g * GRPCServerRW ) Close () error {
85+ logrus .Debugf ("closing GRPCServerRW for id: %s" , g .id )
86+ g .closeCh <- struct {}{}
87+ return nil
88+ }
89+
90+ // By adding CloseRead and CloseWrite methods, GRPCServerRW can work with
91+ // other than containers/gvisor-tap-vsock/pkg/tcpproxy, e.g., inetaf/tcpproxy, bicopy.Bicopy.
92+
93+ func (g * GRPCServerRW ) CloseRead () error {
94+ logrus .Debugf ("closing read GRPCServerRW for id: %s" , g .id )
95+ g .closeCh <- struct {}{}
96+ return nil
97+ }
98+
99+ func (g * GRPCServerRW ) CloseWrite () error {
100+ logrus .Debugf ("closing write GRPCServerRW for id: %s" , g .id )
101+ g .closeCh <- struct {}{}
87102 return nil
88103}
89104
@@ -106,13 +121,3 @@ func (g *GRPCServerRW) SetReadDeadline(_ time.Time) error {
106121func (g * GRPCServerRW ) SetWriteDeadline (_ time.Time ) error {
107122 return nil
108123}
109-
110- // seemsWSL2 returns whether lima.env contains LIMA_CIDATA_VMTYPE=wsl2 .
111- // This is a temporary workaround and has to be removed.
112- func seemsWSL2 () (bool , error ) {
113- b , err := os .ReadFile ("/mnt/lima-cidata/lima.env" )
114- if err != nil {
115- return false , err
116- }
117- return strings .Contains (string (b ), "LIMA_CIDATA_VMTYPE=wsl2" ), nil
118- }
0 commit comments