This topic provides information that is specific to working with the vsock socket on Windows instances.
Topics
Terminology
- Service Provider Interface
-
The Service Provider Interface (SPI) is a library registered with the Windows Sockets 2 (Winsock2) API to support a new address family for the vsock socket. The vsock SPI is available in a 64-bit version only. Only 64-bit applications can use vsock sockets.
- Port
-
The port component of an address. This is a 32-bit unsigned value.
- Local address
-
The address of a vsock socket on the host on which the application is running. The address includes a context identifier (CID) and a port. The CID and port value pairs are concatenated with a '
.
' when written as a string. For example, a host with CID of3
that listens on port1234
has a listening address of3.1234
. - Peer
-
A host that this host is communicating with over the vsock socket.
- Remote address
-
The address of the vsock socket of the peer. The address includes a context identifier (CID) and a port. The CID and port value pairs are concatenated with a '
.
' when written as a string. For example, a host with CID of3
that listens on port1234
has a listening address of3.1234
.
AWS vsock socket implementation
The following are considerations for vsock socket implementation using Winsock2.
Build-time dependencies
Some value definitions are required to create and interact with vsock
sockets. These include the definitions of AF_VSOCK
,
sockaddr_vm
, and some reserved values for CIDs and
ports. It is recommended that you include these definitions by including
the VirtioVsock.h
header in your code. For more
information, about the header, see the Nitro Enclaves SDK Github repository
Runtime
To create a Winsock2 socket with the AF_VSOCK
address
family, the vsock SPI must be registered with Winsock2. The vsock SPI is
registered during the AWS Nitro Enclaves installation. Currently, the vsock
SPI is available in a 64-bit version and supports only 64-bit
applications. For more information about installing AWS Nitro Enclaves on a
Windows instance, see Install Nitro CLI.
Loopback support
Loopback is not supported with vsock sockets. Attempts to
connect()
to a CID that belongs to the same host could
result in an error.
Using the Winsock2 functions with vsock
sockets
This section highlights differences between the Winsock2 functions and the AWS implementation for the vsock SPI.
Note
Functions not listed below follow the Winsock2 implementation and
behave as described in the Winsock2 API documentation
Topics
WSAAccept()/accept()
If a vsock transport reset or device disable event occurs after
receiving a connection request, but before accept()
is
called, accept()
returns an invalid socket and
WSAGetLastError()
returns the value
WSAECONNRESET
.
WSAAddressToString()
Converts sockaddr_vm
to a string in the
CID.Port
format.
WSABind()/bind()
To create a connection using a specific local port, you must call
bind()
with a valid local CID and the desired local
port before calling connect()
. An enclave-enabled Amazon EC2
instance is always assigned local CID of 3
. A socket bound
to SOCKADDR_VM_CID_ANY
can only be used for listening and
cannot be used with connect()
. SO_REUSEADDR
and SO_EXCLUSIVEADDRUSE
are not configurable. AWS vsock
sockets behave as if SO_EXCLUSIVEADDRUSE
is enabled for all
sockets. That is, if any socket is bound to a local
CID.port
pair, no other socket can bind to that same
local CID.port
except as an accept()
from a
listening socket that is bound to SOCKADDR_VM_CID_ANY.port
or CID.port
. Additionally, sockets cannot be bound to
SOCKADDR_VM_CID_ANY.port
when any other socket on the
host is bound to an address with the same local port value and any
CID.
WSAConnect()/connect()
Outgoing connection requests have a non-configurable 1
second timeout before the peer responds with a connection acceptance
packet. When using WSAConnect()
, caller data and callee
data are not supported. Specifying caller data results in an error and
specifying callee data returns a length of 0
. QOS options
are also not supported and return an error if specified.
WSAEventSelect()
FD_OOB
, FD_QOS
, FD_GROUP_QOS
,
FD_ROUTING_INTERFACE_CHANGE
, and
FD_ADDRESS_LIST_CHANGE
will never be signaled in the
current implementation. However, they do not return an error if
specified.
WSAGetPeerName()
Gets the peer’s socket address as a sockaddr_vm
.
WSAGetSockName()
Gets the local socket address as a sockaddr_vm
.
WSAGetSockOpt()/getsockopt()
Only the following optname
parameters are
supported:
-
SO_LINGER
-
SO_DONTLINGER
-
SO_RCVBUF
-
SO_ACCEPTCONN
-
SO_PROTOCOL_INFOW
-
SO_TYPE
For more information, see getsockopt function
WSAIoctl()/ioctlsocket()
Only the following ioctls
are supported:
-
FIONBIO
-
FIONREAD
For more information, see ioctlsocket function
WSAListen()/listen()
Setting a backlog size of 0
or less sets the backlog size
to 0
. Setting the backlog size to a value greater than the
implementation-specific maximum backlog size, which is currently
2048
, sets the backlog size to the
implementation-specific maximum backlog size. Reducing the backlog size
while connection requests exist on a listening socket rejects some of
the connection requests until the number of connections is equal to, or
less than, the new backlog size.
WSASend()/send()
No flags are supported for these functions. The flag values must be
set to 0
. If you specify a different value, an error is
returned.
WSASetSockOpt()/setsockopt()
This function follows the Winsock2 implementation. However, only the following options are supported:
-
SO_LINGER
-
SO_DONTLINGER
-
SO_RCVBUF
SO_RCVBUF
has a minimum value of 4096
bytes
and a maximum value of 2
MB. Requested buffer sizes are
rounded down to a power of 2
, or to 2
MB if
the value is greater than 2
MB. Received buffer size
defaults to 256
KB.
For more information, see ioctlsocket function
WSASocket()/socket()
This function returns a new SOCKET
. With the AWS vsock
SPI, this SOCKET
is also a HANDLE
that allows
you to call functions, such as ReadFile
and
WriteFile
directly on the SOCKET
.
This function must be called with af = AF_VSOCK
and
type = SOCK_STREAM
. Only the
WSA_FLAG_OVERLAPPED
flag is supported when calling
WSASocket()
, which allows overlapped IO on the
SOCKET
that is returned. If socket()
is
called, the WSA_FLAG_OVERLAPPED
flag is set. For more
information about overlapped creation of sockets, see socket function
WSAStringToAddress()
Converts a string in the format of CID.Port
to a
sockaddr_vm
.
WSARecv()/recv()
Only the MSG_PEEK
flag is supported for this
function.
Unsupported Winsock2 functions
The following Winsock2 functions are not supported with AWS vsock sockets.
-
WSACancelBlockingCall()
-
WSAAsyncSelect()
-
WSAGetQosByName()
-
WSAJoinLeaf()
-
WSARecvDisconnect()
-
WSASendDisconnect()
-
WSARecvFrom()
-
WSASendTo()
Known issues
Some IOs cannot be canceled
When calling WSASend()
, WSARecv()
, or
WSAIoctl()
on an overlapped socket, either with
lpOverlapped
omitted or with
lpCompletionRoutine
specified, the IO cannot be
canceled by the user using CancelIo
or
CancelIoEx
. CancelIoEx
returns an error
with GetLastError()
returning ERROR_NOT_FOUND
.
All IOs can be canceled by calling closesocket()
.