+#ifdef EXIM_HAVE_ALPN
+/* Expand and convert an Exim list to an ALPN list. False return for fail.
+NULL plist return for silent no-ALPN.
+*/
+
+static BOOL
+tls_alpn_plist(const uschar * tls_alpn, const uschar ** plist, unsigned * plen,
+ uschar ** errstr)
+{
+uschar * exp_alpn;
+
+if (!expand_check(tls_alpn, US"tls_alpn", &exp_alpn, errstr))
+ return FALSE;
+
+if (!exp_alpn)
+ {
+ DEBUG(D_tls) debug_printf("Setting TLS ALPN forced to fail, not sending\n");
+ *plist = NULL;
+ }
+else
+ {
+ /* The server implementation only accepts exactly one protocol name
+ but it's little extra code complexity in the client. */
+
+ const uschar * list = exp_alpn;
+ uschar * p = store_get(Ustrlen(exp_alpn), is_tainted(exp_alpn)), * s, * t;
+ int sep = 0;
+ uschar len;
+
+ for (t = p; s = string_nextinlist(&list, &sep, NULL, 0); t += len)
+ {
+ *t++ = len = (uschar) Ustrlen(s);
+ memcpy(t, s, len);
+ }
+ *plist = (*plen = t - p) ? p : NULL;
+ }
+return TRUE;
+}
+#endif /* EXIM_HAVE_ALPN */
+
+