]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Make VMCI Stream Sockets use control packet destination for binding.
authorVMware, Inc <>
Tue, 29 Mar 2011 20:13:01 +0000 (13:13 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 29 Mar 2011 20:13:01 +0000 (13:13 -0700)
When creating a VMCI stream socket connection, the protocol
calls VMCI_GetContextID() to set the local CID of a
connection. However, in the nested VM case, this may no longer
be correct, since a given connection can either be a host CID
endpoint or a guest CID endpoint. Instead, we can use an
incoming control packet to determine what destination CID the
peer is using when sending to us, and use that as our local CID.

For server side sockets, the change is simple - instead of
calling VMCI_GetContextID() to set the local CID when
receiving a request packet, we use the dst cid of the
packet. For the client side, we delay the assignment of the
local CID until we receive the negotiate packet from the
server side. Until then, a connecting socket will continue to
have the local CID of any - just like a listening
socket. Since all sockets share the same port range regardless
of their CID, no additional port conflicts will arise from
this.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/modules/linux/vsock/linux/af_vsock.c

index 35cc262d2cf50a817d1048862a527a3d89b8584a..da640b4eb0f4755d5521de71b5c9e27657bc5258 100644 (file)
@@ -1651,7 +1651,7 @@ VSockVmciRecvListen(struct sock *sk,   // IN
    ASSERT(vsk->localAddr.svm_port == pkt->dstPort);
 
    VSockAddr_Init(&vpending->localAddr,
-                  VMCI_GetContextID(),
+                  VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst),
                   pkt->dstPort);
    VSockAddr_Init(&vpending->remoteAddr,
                   VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.src),
@@ -2139,6 +2139,14 @@ VSockVmciRecvConnectingClientNegotiate(struct sock *sk,   // IN: socket
       goto destroy;
    }
 
+   /*
+    * At this point we know the CID the peer is using to talk to us.
+    */
+
+   if (vsk->localAddr.svm_cid == VMADDR_CID_ANY) {
+      vsk->localAddr.svm_cid = VMCI_HANDLE_TO_CONTEXT_ID(pkt->dg.dst);
+   }
+
    /*
     * Setup the notify ops to be the highest supported version that both the
     * server and the client support.
@@ -3642,14 +3650,6 @@ VSockVmciStreamConnect(struct socket *sock,   // IN
          }
       }
 
-      /*
-       * For the client stream sockets, we always want to make sure that
-       * we have a specific context id.
-       */
-      if (vsk->localAddr.svm_cid == VMADDR_CID_ANY) {
-         vsk->localAddr.svm_cid = VMCI_GetContextID();
-      }
-
       sk->sk_state = SS_CONNECTING;
 
       if (VSockVmciOldProtoOverride(&oldPktProto) && oldPktProto) {