Porting Existing Socket Applications
Modifying existing socket implementations is straightforward. This chapter describes the lines of code you must change.
Include a New Header File
To obtain the definitions for vSockets, include the vmci_sockets.h header file.
#include "vmci_sockets.h"
Change AF_INET to vSockets
Call VMCISock_GetAFValue() to obtain the VMCI address family. Declare structure sockaddr_vm instead of sockaddr_in. In the socket() call, replace the AF_INET address family with the VMCI address family.
When the client creates a connection, instead of providing an IP address to choose its server, the client must provide the context ID (CID) of a virtual machine or host. An application running on a virtual machine uses the local context ID for bind() and a remote context ID for connect().
Obtain the CID
In virtual hardware version 6 (Workstation 6.0.x releases), the VMCI virtual device is not present by default. After you upgrade a virtual machine’s virtual hardware to version 7, the following line appears in the .vmx configuration file, and when the virtual machine powers on, a new vmci0.id line also appears there.
vmci0.present = "TRUE"
In virtual hardware version 7 (Workstation 6.5 releases), the VMCI virtual device is present by default. When you create a virtual machine, the .vmx configuration file contains lines specifying PCI slot number and the ID of the VMCI device. On the vmci0.id line, CID is the number in double quotes.
vmci0.pciSlotNumber = "36"
vmci0.id = "1066538581"
The VMCISock_GetLocalCID() Function
For convenience, you can call the VMCISock_GetLocalCID() function to obtain the local system’s CID. This function works on both the ESXi host and guest virtual machines, although the ESXi host always has CID = 2, even in a nested virtual machine (VM running in a VM).
Connection-Oriented Stream Socket
To establish a stream socket, include these declarations and calls, and replace AF_INET with afVMCI, as set by VMCISock_GetAFValue().
int sockfd_stream;
int afVMCI = VMCISock_GetAFValue();
if ((sockfd_stream = socket(afVMCI, SOCK_STREAM, 0)) == -1) {
perror(“Socket stream”);
}
Connectionless Datagram Socket
To establish a datagram socket, include these declarations and calls:
int sockfd_dgram;
int afVMCI = VMCISock_GetAFValue();
if ((sockfd_dgram = socket(afVMCI, SOCK_DGRAM, 0)) == -1) {
perror(“Socket datagram”);
}
Initializing the Address Structure
To initialize the address structure passed to bind(), insert these source code statements, where sockaddr_vm for vSockets replaces sockaddr_in for network sockets.
struct sockaddr_vm my_addr = {0};
my_addr.svm_family = afVMCI;
my_addr.svm_cid = VMADDR_CID_ANY;
my_addr.svm_port = VMADDR_PORT_ANY;
The first line declares my_addr as a sockaddr_vm structure and initializes it with zeros. AF_INET replaces afVMCI. Both VMADDR_CID_ANY and VMADDR_PORT_ANY are predefined so that at runtime, the server can fill in the appropriate CID and port values during a bind operation. The initiating side of the connection, the client, must provide the CID and port, instead of VMADDR_CID_ANY and VMADDR_PORT_ANY.