summaryrefslogtreecommitdiffstats
path: root/src/vcl/ldp.c
diff options
context:
space:
mode:
authorYu Ping <ping.yu@intel.com>2019-05-08 00:40:24 +0800
committerFlorin Coras <florin.coras@gmail.com>2019-05-09 03:18:20 +0000
commit7b74b073e4e351fdc0ca1f94655c572405176a1b (patch)
tree93a29c80d5eeb399d81b54507c8f48b9debbd46f /src/vcl/ldp.c
parentf40ee3a206b2abd2ca2b8b94e0d233c2f1ade801 (diff)
ldp: add option to eanble transparent TLS connections
If LDP_TRANSPARENT_TLS is set, LDP transparently converts TCP into TLS connnection. Verified in Nginx LD_PRELOAD mode. Change-Id: I2229be61a0deb723bf5d94a2193ecb792dd997fb Signed-off-by: Yu Ping <ping.yu@intel.com>
Diffstat (limited to 'src/vcl/ldp.c')
-rw-r--r--src/vcl/ldp.c89
1 files changed, 87 insertions, 2 deletions
diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
index 6dc44ece42f..70a4299083e 100644
--- a/src/vcl/ldp.c
+++ b/src/vcl/ldp.c
@@ -99,6 +99,7 @@ typedef struct
u32 vlsh_bit_val;
u32 vlsh_bit_mask;
u32 debug;
+ u8 transparent_tls;
/** vcl needs next epoll_create to go to libc_epoll */
u8 vcl_needs_real_epoll;
@@ -114,6 +115,7 @@ static ldp_main_t ldp_main = {
.vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
.vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
.debug = LDP_DEBUG_INIT,
+ .transparent_tls = 0,
};
static ldp_main_t *ldp = &ldp_main;
@@ -268,6 +270,11 @@ ldp_init (void)
return -1;
}
}
+ env_var_str = getenv (LDP_ENV_TLS_TRANS);
+ if (env_var_str)
+ {
+ ldp->transparent_tls = 1;
+ }
/* *INDENT-OFF* */
pool_foreach (ldpw, ldp->workers, ({
@@ -870,6 +877,71 @@ pselect (int nfds, fd_set * __restrict readfds,
}
#endif
+/* If transparent TLS mode is turned on, then ldp will load key and cert.
+ */
+static int
+load_tls_cert (vls_handle_t vlsh)
+{
+ char *env_var_str = getenv (LDP_ENV_TLS_CERT);
+ char inbuf[4096];
+ char *tls_cert;
+ int cert_size;
+ FILE *fp;
+
+ if (env_var_str)
+ {
+ fp = fopen (env_var_str, "r");
+ if (fp == NULL)
+ {
+ LDBG (0, "ERROR: failed to open cert file %s \n", env_var_str);
+ return -1;
+ }
+ cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
+ tls_cert = inbuf;
+ vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
+ cert_size);
+ fclose (fp);
+ }
+ else
+ {
+ LDBG (0, "ERROR: failed to read LDP environment %s\n",
+ LDP_ENV_TLS_CERT);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+load_tls_key (vls_handle_t vlsh)
+{
+ char *env_var_str = getenv (LDP_ENV_TLS_KEY);
+ char inbuf[4096];
+ char *tls_key;
+ int key_size;
+ FILE *fp;
+
+ if (env_var_str)
+ {
+ fp = fopen (env_var_str, "r");
+ if (fp == NULL)
+ {
+ LDBG (0, "ERROR: failed to open key file %s \n", env_var_str);
+ return -1;
+ }
+ key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
+ tls_key = inbuf;
+ vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
+ key_size);
+ fclose (fp);
+ }
+ else
+ {
+ LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY);
+ return -1;
+ }
+ return 0;
+}
+
int
socket (int domain, int type, int protocol)
{
@@ -883,8 +955,14 @@ socket (int domain, int type, int protocol)
if (((domain == AF_INET) || (domain == AF_INET6)) &&
((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
{
- u8 proto = ((sock_type == SOCK_DGRAM) ?
- VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
+ u8 proto;
+ if (ldp->transparent_tls)
+ {
+ proto = VPPCOM_PROTO_TLS;
+ }
+ else
+ proto = ((sock_type == SOCK_DGRAM) ?
+ VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
proto, vppcom_proto_str (proto), is_nonblocking);
@@ -897,6 +975,13 @@ socket (int domain, int type, int protocol)
}
else
{
+ if (ldp->transparent_tls)
+ {
+ if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
+ {
+ return -1;
+ }
+ }
rv = ldp_vlsh_to_fd (vlsh);
}
}