---
name: "libressl-SSL_CTX_set_alpn_select_cb"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-SSL_CTX_set_alpn_select_cb"
---

# libressl-SSL\_CTX\_set\_alpn\_select\_cb(3)

handle application layer protocol negotiation (ALPN)

## NAME

**SSL\_CTX\_set\_alpn\_protos**, **SSL\_set\_alpn\_protos**, **SSL\_CTX\_set\_alpn\_select\_cb**, **SSL\_select\_next\_proto**, **SSL\_get0\_alpn\_selected** – handle application layer protocol negotiation (ALPN)

## SYNOPSIS

SSL Library (libssl, -lssl) libcrypto

**#include \<openssl/ssl.h\>**

*int*\

**SSL\_CTX\_set\_alpn\_protos**(*SSL\_CTX \*ctx*, *const unsigned char \*protos*, *unsigned int protos\_len*);

*int*\

**SSL\_set\_alpn\_protos**(*SSL \*ssl*, *const unsigned char \*protos*, *unsigned int protos\_len*);

*void*\

**SSL\_CTX\_set\_alpn\_select\_cb**(*SSL\_CTX \*ctx*, *int (\*cb)(SSL \*ssl, const unsigned char \*\*out, unsigned char \*outlen, const unsigned char \*in, unsigned int inlen, void \*arg)*, *void \*arg*);

*int*\

**SSL\_select\_next\_proto**(*unsigned char \*\*out*, *unsigned char \*outlen*, *const unsigned char \*peer\_list*, *unsigned int peer\_list\_len*, *const unsigned char \*supported\_list*, *unsigned int supported\_list\_len*);

*void*\

**SSL\_get0\_alpn\_selected**(*const SSL \*ssl*, *const unsigned char \*\*data*, *unsigned int \*len*);

## DESCRIPTION

**SSL\_CTX\_set\_alpn\_protos**() and **SSL\_set\_alpn\_protos**() are used by the client to set the list of protocols available to be negotiated. The *protos* must be in protocol-list format, described below. The length of *protos* is specified in *protos\_len*.

**SSL\_CTX\_set\_alpn\_select\_cb**() sets the application callback *cb* used by a server to select which protocol to use for the incoming connection. When *cb* is NULL, ALPN is not used. The *arg* value is a pointer which is passed to the application callback.

*cb* is the application defined callback. The *in*, *inlen* parameters are a vector in protocol-list format. The value of the *out*, *outlen* vector should be set to the value of a single protocol selected from the *in*, *inlen* vector. The *out* buffer may point directly into *in*, or to a buffer that outlives the handshake. The *arg* parameter is the pointer set via **SSL\_CTX\_set\_alpn\_select\_cb**().

**SSL\_select\_next\_proto**() is a helper function used to select protocols. It is expected that this function is called from the application callback *cb*. If **SSL\_select\_next\_proto**() returns OPENSSL\_NPN\_NO\_OVERLAP, *cb* should ignore *out* and fail by returning SSL\_TLSEXT\_ERR\_ALERT\_FATAL. The protocol data in *peer\_list*, *peer\_list\_len* and *supported\_list*, *supported\_list\_len* must be two non-empty lists, validly encoded in the protocol-list format described below. The first item in the *peer\_list* that matches an item in the *supported\_list* is selected, and returned in *out*, *outlen*. The *out* value will point into either *peer\_list* or *supported\_list*, so it must not be modified and should be copied immediately. If no match is found, the first item in *supported\_list* is returned in *out*, *outlen*.

**SSL\_get0\_alpn\_selected**() returns a pointer to the selected protocol in *data* with length *len*. It is not NUL-terminated. *data* is set to NULL and *len* is set to 0 if no protocol has been selected. *data* must not be freed.

The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed byte strings. The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid. The length of the vector is not in the vector itself, but in a separate variable.

For example:

```
const unsigned char *vector = "\x06" "spdy/1" "\x08" "http/1.1";
unsigned int length = strlen(vector);
```

The ALPN callback is executed after the servername callback; as that servername callback may update the SSL\_CTX, and subsequently, the ALPN callback.

If there is no ALPN proposed in the ClientHello, the ALPN callback is not invoked.

## RETURN VALUES

**SSL\_CTX\_set\_alpn\_protos**() and **SSL\_set\_alpn\_protos**() return 0 on success or non-zero on failure. WARNING: these functions reverse the return value convention.

**SSL\_select\_next\_proto**() returns one of the following:

- OPENSSL\_NPN\_NEGOTIATED

  A match was found and is returned in *out*, *outlen*.

- OPENSSL\_NPN\_NO\_OVERLAP

  No match was found. The first item in *supported\_list*, *supported\_list\_len* is returned in *out*, *outlen*.

The ALPN select callback *cb* must return one of the following:

- SSL\_TLSEXT\_ERR\_OK

  ALPN protocol selected.

- SSL\_TLSEXT\_ERR\_ALERT\_FATAL

  There was no overlap between the client's supplied list and the server configuration.

- SSL\_TLSEXT\_ERR\_NOACK

  ALPN protocol not selected, e.g., because no ALPN protocols are configured for this connection.

## SEE ALSO

[ssl(3)](/ssl/3.md), SSL\_CTX\_set\_tlsext\_servername\_arg(3), SSL\_CTX\_set\_tlsext\_servername\_callback(3)

## STANDARDS

*TLS Application-Layer Protocol Negotiation Extension*, RFC 7301.

*TLS Next Protocol Negotiation Extension*, https://datatracker.ietf.org/doc/html/draft-agl-tls-nextprotoneg.

## HISTORY

**SSL\_select\_next\_proto**() first appeared in OpenSSL 1.0.1 and has been available since OpenBSD 5.3.

**SSL\_CTX\_set\_alpn\_protos**(), **SSL\_set\_alpn\_protos**(), **SSL\_CTX\_set\_alpn\_select\_cb**(), and **SSL\_get0\_alpn\_selected**() first appeared in OpenSSL 1.0.2 and have been available since OpenBSD 5.7.

## CAVEATS

The fallback to the first supported protocol in **SSL\_select\_next\_proto**() comes from the opportunistic fallback mechanism in the NPN extension. This behavior does not make sense for ALPN, where missing protocol overlap should result in a handshake failure. To avoid accidental selection of a protocol that the server does not support, it is recommended to pass the locally configured protocols as second pair of protocols in the ALPN callback.

## BUGS

The *out* argument of **SSL\_select\_next\_proto**() should have been const.
