mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-24 03:15:36 +00:00
proxy: fix up the vsock interface
- don't try to create a `FileConn` because the Go library sees through the scam and rejects it - explicitly keep a reference to the `ctl` file just in case the GC decides its dead and should be closed. Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
parent
1d3b8b566e
commit
586d9c0598
@ -8,53 +8,57 @@ import (
|
||||
"os"
|
||||
"libproxy"
|
||||
"strings"
|
||||
"vsock"
|
||||
)
|
||||
|
||||
func main() {
|
||||
host, port, container := parseHostContainerAddrs()
|
||||
|
||||
err := exposePort(host, port)
|
||||
ctl, err := exposePort(host, port)
|
||||
if err != nil {
|
||||
sendError(err)
|
||||
}
|
||||
p, err := libproxy.NewProxy(host, container)
|
||||
|
||||
p, err := libproxy.NewProxy(&vsock.VsockAddr{Port: uint(port)}, container)
|
||||
if err != nil {
|
||||
sendError(err)
|
||||
}
|
||||
|
||||
go handleStopSignals(p)
|
||||
sendOK()
|
||||
p.Run()
|
||||
ctl.Close() // ensure ctl remains alive and un-GCed until here
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func exposePort(host net.Addr, port int) error {
|
||||
func exposePort(host net.Addr, port int) (*os.File, error) {
|
||||
name := host.String()
|
||||
log.Printf("exposePort %s\n", name)
|
||||
err := os.Mkdir("/port/"+name, 0)
|
||||
if err != nil {
|
||||
log.Printf("Failed to mkdir /port/%s: %#v\n", name, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
ctl, err := os.OpenFile("/port/"+name+"/ctl", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
_, err = ctl.WriteString(fmt.Sprintf("%s:%08x", name, port))
|
||||
if err != nil {
|
||||
log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
_, err = ctl.Seek(0, 0)
|
||||
if err != nil {
|
||||
log.Printf("Failed to seek on /port/%s/ctl: %#v\n", name, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
results := make([]byte, 100)
|
||||
count, err := ctl.Read(results)
|
||||
if err != nil {
|
||||
log.Printf("Failed to read from /port/%s/ctl: %#v\n", name, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
// We deliberately keep the control file open since 9P clunk
|
||||
// will trigger a shutdown on the host side.
|
||||
@ -63,8 +67,8 @@ func exposePort(host net.Addr, port int) error {
|
||||
if strings.HasPrefix(response, "ERROR ") {
|
||||
os.Remove("/port/" + name + "/ctl")
|
||||
response = strings.Trim(response[6:], " \t\r\n")
|
||||
return errors.New(response)
|
||||
return nil, errors.New(response)
|
||||
}
|
||||
|
||||
return nil
|
||||
// Hold on to a reference to prevent premature GC and close
|
||||
return ctl, nil
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
|
||||
}
|
||||
return NewTCPProxy(listener, backendAddr.(*net.TCPAddr))
|
||||
case *vsock.VsockAddr:
|
||||
listener, err := vsock.Listen(frontendAddr.(vsock.VsockAddr).Port)
|
||||
listener, err := vsock.Listen(frontendAddr.(*vsock.VsockAddr).Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
33
alpine/packages/proxy/vendor/vsock/vsock.go
vendored
33
alpine/packages/proxy/vendor/vsock/vsock.go
vendored
@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
/* No way to teach net or syscall about vsock sockaddr, so go right to C */
|
||||
@ -101,7 +102,7 @@ func (v *vsockListener) Addr() net.Addr {
|
||||
|
||||
// a wrapper around FileConn which supports CloseRead and CloseWrite
|
||||
type vsockConn struct {
|
||||
net.Conn
|
||||
vsock *os.File
|
||||
fd uintptr
|
||||
local VsockAddr
|
||||
remote VsockAddr
|
||||
@ -113,13 +114,9 @@ type VsockConn struct {
|
||||
|
||||
func newVsockConn(fd uintptr, localPort uint) (*VsockConn, error) {
|
||||
vsock := os.NewFile(fd, fmt.Sprintf("vsock:%d", fd))
|
||||
conn, err := net.FileConn(vsock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
local := VsockAddr{Port: localPort}
|
||||
remote := VsockAddr{Port: uint(0)} // FIXME
|
||||
return &VsockConn{vsockConn{Conn: conn, fd: fd, local: local, remote: remote}}, nil
|
||||
return &VsockConn{vsockConn{vsock: vsock, fd: fd, local: local, remote: remote}}, nil
|
||||
}
|
||||
|
||||
func (v *VsockConn) LocalAddr() net.Addr {
|
||||
@ -137,3 +134,27 @@ func (v *VsockConn) CloseRead() error {
|
||||
func (v *VsockConn) CloseWrite() error {
|
||||
return syscall.Shutdown(int(v.fd), syscall.SHUT_WR)
|
||||
}
|
||||
|
||||
func (v *VsockConn) Close() error {
|
||||
return v.vsock.Close()
|
||||
}
|
||||
|
||||
func (v *VsockConn) Read(buf []byte) (int, error) {
|
||||
return v.vsock.Read(buf)
|
||||
}
|
||||
|
||||
func (v *VsockConn) Write(buf []byte) (int, error) {
|
||||
return v.vsock.Write(buf)
|
||||
}
|
||||
|
||||
func (v *VsockConn) SetDeadline(t time.Time) error {
|
||||
return nil // FIXME
|
||||
}
|
||||
|
||||
func (v *VsockConn) SetReadDeadline(t time.Time) error {
|
||||
return nil // FIXME
|
||||
}
|
||||
|
||||
func (v *VsockConn) SetWriteDeadline(t time.Time) error {
|
||||
return nil // FIXME
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user