diff options
author | Yu Ping <ping.yu@intel.com> | 2019-05-08 00:40:24 +0800 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-05-09 03:18:20 +0000 |
commit | 7b74b073e4e351fdc0ca1f94655c572405176a1b (patch) | |
tree | 93a29c80d5eeb399d81b54507c8f48b9debbd46f /src/vcl/ldp.c | |
parent | f40ee3a206b2abd2ca2b8b94e0d233c2f1ade801 (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.c | 89 |
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); } } |