+#ifdef EXIM_HAVE_ALPN
+/*************************************************
+* Callback to handle ALPN *
+*************************************************/
+
+/* SSL_CTX_set_alpn_select_cb() */
+/* Called on server when client offers ALPN, after the SNI callback.
+If set and not e?smtp then we dump the connection */
+
+static int
+tls_server_alpn_cb(SSL *ssl, const uschar ** out, uschar * outlen,
+ const uschar * in, unsigned int inlen, void * arg)
+{
+const exim_openssl_state_st * state = arg;
+
+DEBUG(D_tls)
+ {
+ debug_printf("Received TLS ALPN offer:");
+ for (int pos = 0, siz; pos < inlen; pos += siz+1)
+ {
+ siz = in[pos];
+ if (pos + 1 + siz > inlen) siz = inlen - pos - 1;
+ debug_printf(" '%.*s'", siz, in + pos + 1);
+ }
+ debug_printf("\n");
+ }
+
+/* Look for an acceptable ALPN */
+if ( inlen > 1 /* at least one name */
+ && in[0]+1 == inlen /* filling the vector, so exactly one name */
+ && ( Ustrncmp(in+1, "smtp", in[0]) == 0
+ || Ustrncmp(in+1, "esmtp", in[0]) == 0
+ ) )
+ {
+ *out = in; /* we checked for exactly one, so can just point to it */
+ *outlen = inlen;
+ return SSL_TLSEXT_ERR_OK; /* use ALPN */
+ }
+
+/* Reject unacceptable ALPN */
+/* This will be fatal to the TLS conn; would be nice to kill TCP also */
+return SSL_TLSEXT_ERR_ALERT_FATAL;
+}
+#endif /* EXIM_HAVE_ALPN */
+
+
+