Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
protocols/client: improve hybrid vsock parser
Browse files Browse the repository at this point in the history
improve hybrid vsock parser to get the port if it's provided
and use it in the dialer to connect the hybrid vsock

Signed-off-by: Julio Montes <[email protected]>
  • Loading branch information
Julio Montes committed Oct 3, 2019
1 parent 6a96997 commit a03e23b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
32 changes: 24 additions & 8 deletions protocols/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,26 @@ func parseGrpcVsockAddr(sock string) (uint32, uint32, error) {
return uint32(cid), uint32(port), nil
}

func parseGrpcHybridVSockAddr(sock string) (string, error) {
func parseGrpcHybridVSockAddr(sock string) (string, uint32, error) {
sp := strings.Split(sock, ":")
if len(sp) != 2 {
return "", grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock address: %s", sock)
// scheme and host are required
if len(sp) < 2 {
return "", 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock address: %s", sock)
}
if sp[0] != hybridVSockScheme {
return "", grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock URL scheme: %s", sock)
if sp[0] != HybridVSockScheme {
return "", 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock URL scheme: %s", sock)
}

return sp[1], nil
port := uint32(0)
// the third is the port
if len(sp) == 3 {
p, err := strconv.ParseUint(sp[2], 10, 32)
if err == nil {
port = uint32(p)
}
}

return sp[1], port, nil
}

// This would bypass the grpc dialer backoff strategy and handle dial timeout
Expand Down Expand Up @@ -373,7 +383,7 @@ func vsockDialer(sock string, timeout time.Duration) (net.Conn, error) {

// HybridVSockDialer dials to a hybrid virtio socket
func HybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) {
udsPath, err := parseGrpcHybridVSockAddr(sock)
udsPath, port, err := parseGrpcHybridVSockAddr(sock)
if err != nil {
return nil, err
}
Expand All @@ -383,10 +393,16 @@ func HybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) {
if err != nil {
return nil, err
}

if port == 0 {
// use the port read at parse()
port = hybridVSockPort
}

// Once the connection is opened, the following command MUST BE sent,
// the hypervisor needs to know the port number where the agent is listening in order to
// create the connection
if _, err = conn.Write([]byte(fmt.Sprintf("CONNECT %d\n", hybridVSockPort))); err != nil {
if _, err = conn.Write([]byte(fmt.Sprintf("CONNECT %d\n", port))); err != nil {
conn.Close()
return nil, err
}
Expand Down
12 changes: 9 additions & 3 deletions protocols/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,22 @@ func TestNewAgentClientWithYamux(t *testing.T) {
func TestParseGrpcHybridVSockAddr(t *testing.T) {
assert := assert.New(t)

a, err := parseGrpcHybridVSockAddr("/abc/xyz")
a, _, err := parseGrpcHybridVSockAddr("/abc/xyz")
assert.Error(err)
assert.Empty(a)

a, err = parseGrpcHybridVSockAddr("sss:/abc/xyz")
a, _, err = parseGrpcHybridVSockAddr("sss:/abc/xyz")
assert.Error(err)
assert.Empty(a)

path := "/abc/xyz"
a, err = parseGrpcHybridVSockAddr(hybridVSockScheme + ":" + path)
a, _, err = parseGrpcHybridVSockAddr(HybridVSockScheme + ":" + path)
assert.NoError(err)
assert.Equal(a, path)

port := uint32(512)
a, p, err := parseGrpcHybridVSockAddr(fmt.Sprintf("%s:%s:%d", HybridVSockScheme, path, port))
assert.NoError(err)
assert.Equal(a, path)
assert.Equal(p, port)
}

0 comments on commit a03e23b

Please sign in to comment.