---
name: "connectx"
section: "2"
platform: "macos"
package: "xnu"
version: "12377.121.6"
release: "macOS 26.5"
platforms: ["macos"]
url: "https://new.carta.tech/connectx"
---

# connectx(2)

initiate a connection on a socket

## NAME

**connectx** – initiate a connection on a socket

## SYNOPSIS

**#include \<sys/socket.h\>**

*int*\

**connectx**(*int socket*, *const sa\_endpoints\_t \*endpoints*, *sae\_associd\_t associd*, *unsigned int flags*, *const struct iovec \*iov*, *unsigned int iovcnt*, *size\_t \*len*, *sae\_connid\_t \*connid*);

## DESCRIPTION

The parameter *socket* is a socket. In general, **connectx**() may be used as a substitute for cases when [bind(2)](/bind/2.md) and [connect(2)](/connect/2.md) are issued in succession, as well as a mechanism to transmit data at connection establishment time.

The **connectx**() system call uses a *sa\_endpoints* structure to minimize the number of directly supplied arguments. This structure has the following form, as defined in ⟨sys/socket.h⟩:

```
typedef struct sa_endpoints {
	unsigned int     sae_srcif;      /* optional source interface   */
	struct sockaddr *sae_srcaddr;    /* optional source address     */
	socklen_t        sae_srcaddrlen; /* size of source address      */
	struct sockaddr *sae_dstaddr;    /* destination address         */
	socklen_t        sae_dstaddrlen; /* size of destination address */
}sa_endpoints_t;
```

When the optional source address *sae\_srcaddr* parameter is specified, **connectx**() binds the connection to the address, as if [bind(2)](/bind/2.md) is used.  The length of *sae\_srcaddr* buffer is specified by *sae\_srcaddrlen*. The source address can be obtained by calling [getifaddrs(3)](/getifaddrs/3.md).

The optional parameter *sae\_srcif* may also be specified, in order to force the connection to use the interface whose interface index equals to *sae\_srcif*. The value for *sae\_srcif* may be obtained by issuing a call to [if\_nametoindex(3)](/if_nametoindex/3.md). If only *sae\_srcif* is specified, the communication domain will choose a source address on that interface for communicating to the peer socket.  Both *sae\_srcaddr* and *sae\_srcif* parameters may also be specified in order to add more constraints to the connection, and **connectx**() will fail unless the address is currently assigned to that interface.

A destination address must be specified in the *sae\_dstaddr* parameter.  The *sae\_dstaddrlen* specifies the length of that buffer.

Data to be transmitted may optionally be defined via the *iovcnt* buffers specified by members of the *iov* array, along with a non-NULL *len* parameter, which upon success, indicates the number of bytes enqueued for transmission.

When the *iov* and *len* parameters are non-NULL, the communication domain will copy the data to the socket send buffer. The communication domain may impose a limit on the amount of data allowed to be buffered before connection establishment.

When the flags parameter is set to CONNECT\_RESUME\_ON\_READ\_WRITE and an *iov* is not passed in, the communication domain will trigger the actual connection establishment upon the first read or write following the [connectx(2)](/connectx/2.md) system call. This flag is ignored if the iov is specified in the [connectx(2)](/connectx/2.md) call itself.

The flags parameter may also be set to CONNECT\_DATA\_IDEMPOTENT to indicate to the communication domain that the data is idempotent. For example, this will trigger TCP Fast Open (RFC 7413) with SOCK\_STREAM type. The data must be passed in the *iov* parameter in [connectx(2)](/connectx/2.md) , or passed in with the first write call such as with the [writev(2)](/writev/2.md) or similar system call if the CONNECT\_RESUME\_ON\_READ\_WRITE is also set.

In general, the communication domain makes the final decision on the amount of data that may get transmitted at connection establishment time.  If the socket requires the data be sent atomically and the data size makes this impossible, EMSGSIZE will be returned and the state of the socket is left unchanged as if **connectx**() was not called.

The parameter *associd* is reserved for future use, and must always be set to SAE\_ASSOCID\_ANY. The parameter *connid* is also reserved for future use and should be set to NULL.

## NOTES

**connectx**() is currently supported only on AF\_INET and AF\_INET6 sockets of type SOCK\_DGRAM and SOCK\_STREAM.

Generally, connection-oriented sockets may successfully **connectx**() only once.  Connectionless sockets may use **connectx**() to create an association to the peer socket, and it may call [disconnectx(2)](/disconnectx/2.md) to dissolve any existing association.  Unlike connection-oriented sockets, connectionless sockets may call **connectx**() again afterwards to associate to another peer socket.

If CONNECT\_RESUME\_ON\_READ\_WRITE is set without data  supplied, **connectx**() will immediately return success, assuming the rest of the parameters are valid. [select(2)](/select/2.md) will indicate that the socket is ready for writing, and the actual connection establishment is attempted once the initial data is written to the socket via [writev(2)](/writev/2.md) or similar.  Subsequent attempts to write more data will fail until the existing connection establishment attempt is successful.  The error status of the socket may be retrieved via the SO\_ERROR option using [getsockopt(2)](/getsockopt/2.md).

## RETURN VALUES

Upon successful completion, a value of 0 is returned. The number of bytes from *iov* array which were enqueued for transmission is returned via *len*. Upon failure, a value of -1 is returned and the global integer variable *errno* is set to indicate the error.

## ERRORS

The **connectx**() system call will fail if:

- \[EADDRINUSE\]

  The address specified in *sae\_srcaddr* parameter is already in use.

- \[EADDRNOTAVAIL\]

  The specified in *sae\_srcaddr* parameter is not available on this machine, or is not assigned to the interface specified by *sae\_srcif*.

- \[EAFNOSUPPORT\]

  The *socket* cannot find any usable addresses of a specific address family as required by the communication domain.

- \[EALREADY\]

  A previous connection attempt has not yet been completed.

- \[EBADF\]

  *socket* is not a valid descriptor.

- \[ECONNREFUSED\]

  The attempt to connect was ignored (because the target is not listening for connections) or explicitly rejected.

- \[EFAULT\]

  Part of *iov* or data to be written to *socket* points outside the process's allocated address space.

- \[EHOSTUNREACH\]

  The target host cannot be reached (e.g., down, disconnected).

- \[EINPROGRESS\]

  The connection cannot be completed immediately. It is possible to [select(2)](/select/2.md) for completion by selecting the *socket* for writing.

- \[EINTR\]

  Its execution was interrupted by a signal.

- \[EMSGSIZE\]

  The size of the message exceeds the available send buffer space in the *socket*.

- \[EINVAL\]

  An invalid argument was detected (e.g., *sae\_dstaddrlen* is not valid, the contents of *sae\_srcaddr* or *sae\_dstaddr,* buffer is invalid, etc.)

- \[EISCONN\]

  The socket is already connected.

- \[ENETDOWN\]

  The local network interface is not functioning.

- \[ENETUNREACH\]

  The network isn't reachable from this host.

- \[ENOBUFS\]

  The system call was unable to allocate a needed memory buffer.

- \[ENOTSOCK\]

  *socket* is not a file descriptor for a socket.

- \[EOPNOTSUPP\]

  Because *socket* is listening, no connection is allowed.

- \[ETIMEDOUT\]

  Connection establishment timed out without establishing a connection.

## SEE ALSO

[bind(2)](/bind/2.md), [connect(2)](/connect/2.md), [disconnectx(2)](/disconnectx/2.md), [getsockopt(2)](/getsockopt/2.md), [select(2)](/select/2.md), [socket(2)](/socket/2.md), [writev(2)](/writev/2.md), [compat(5)](/compat/5.md)

## HISTORY

The **connectx**() function call appeared in Darwin 15.0.0
