/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2016-2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
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;
#define LDBG(_lvl, _fmt, _args...) \
if (ldp->debug > _lvl) \
- clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
+ { \
+ int errno_saved = errno; \
+ clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args); \
+ errno = errno_saved; \
+ }
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;
static inline void
ldp_set_app_name (char *app_name)
{
- int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
- "ldp-%d-%s", getpid (), app_name);
-
- if (rv >= LDP_APP_NAME_MAX)
- app_name[LDP_APP_NAME_MAX - 1] = 0;
+ snprintf (ldp->app_name, LDP_APP_NAME_MAX,
+ "ldp-%d-%s", getpid (), app_name);
}
static inline char *
return (fd - ldp->vlsh_bit_val);
}
+static void
+ldp_alloc_workers (void)
+{
+ if (ldp->workers)
+ return;
+ pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
+}
+
static inline int
ldp_init (void)
{
return rv;
}
ldp->vcl_needs_real_epoll = 0;
- pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
+ ldp_alloc_workers ();
ldpw = ldp_worker_get_current ();
char *env_var_str = getenv (LDP_ENV_DEBUG);
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, ({
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
{
- do
+ for (i = 0; i < iovcnt; ++i)
{
- for (i = 0; i < iovcnt; ++i)
+ rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
+ if (rv <= 0)
+ break;
+ else
{
- rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
- if (rv < 0)
+ total += rv;
+ if (rv < iov[i].iov_len)
break;
- else
- {
- total += rv;
- if (rv < iov[i].iov_len)
- break;
- }
}
}
- while ((rv >= 0) && (total == 0));
-
- if (rv < 0)
+ if (rv < 0 && total == 0)
{
errno = -rv;
size = -1;
vlsh = ldp_fd_to_vlsh (fd);
if (vlsh != VLS_INVALID_HANDLE)
{
- do
+ for (i = 0; i < iovcnt; ++i)
{
- for (i = 0; i < iovcnt; ++i)
+ rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
+ if (rv < 0)
+ break;
+ else
{
- rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
- if (rv < 0)
+ total += rv;
+ if (rv < iov[i].iov_len)
break;
- else
- {
- total += rv;
- if (rv < iov[i].iov_len)
- break;
- }
}
}
- while ((rv >= 0) && (total == 0));
- if (rv < 0)
+ if (rv < 0 && total == 0)
{
errno = -rv;
size = -1;
return size;
}
+#ifdef HAVE_FCNTL64
+int
+fcntl64 (int fd, int cmd, ...)
+#else
int
fcntl (int fd, int cmd, ...)
+#endif
{
vls_handle_t vlsh;
int rv = 0;
}
else
{
+#ifdef HAVE_FCNTL64
+ rv = libc_vfcntl64 (fd, cmd, ap);
+#else
rv = libc_vfcntl (fd, cmd, ap);
+#endif
}
va_end (ap);
if (vlsh == VLS_INVALID_HANDLE)
clib_bitmap_set_no_check (*libcb, fd, 1);
else
- clib_bitmap_set_no_check (*vclb, vlsh_to_session_index (vlsh), 1);
+ *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
}));
/* *INDENT-ON* */
si_bits_set = clib_bitmap_last_set (*vclb) + 1;
*si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
+ clib_bitmap_validate (*resultb, *si_bits);
libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
*libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
/* *INDENT-OFF* */
clib_bitmap_foreach (si, vclb, ({
vlsh = vls_session_index_to_vlsh (si);
+ ASSERT (vlsh != VLS_INVALID_HANDLE);
fd = ldp_vlsh_to_fd (vlsh);
if (PREDICT_FALSE (fd < 0))
{
{
if (readfds)
clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
- vec_len (ldpw->rd_bitmap) *
+ vec_len (ldpw->si_rd_bitmap) *
sizeof (clib_bitmap_t));
if (writefds)
clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
- vec_len (ldpw->wr_bitmap) *
+ vec_len (ldpw->si_wr_bitmap) *
sizeof (clib_bitmap_t));
if (exceptfds)
clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
- vec_len (ldpw->ex_bitmap) *
+ vec_len (ldpw->si_ex_bitmap) *
sizeof (clib_bitmap_t));
rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
}
#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)
{
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);
}
else
{
+ if (ldp->transparent_tls)
+ {
+ if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
+ {
+ return -1;
+ }
+ }
rv = ldp_vlsh_to_fd (vlsh);
}
}
{
size = vls_recvfrom (vlsh, buf, n, flags, NULL);
if (size < 0)
- errno = -size;
+ {
+ errno = -size;
+ size = -1;
+ }
}
else
{
rv = -EFAULT;
break;
case TCP_CONGESTION:
- strcpy (optval, "cubic");
*optlen = strlen ("cubic");
+ strncpy (optval, "cubic", *optlen + 1);
rv = 0;
break;
default:
(void *) optval, &optlen);
break;
case TCP_CONGESTION:
+ case TCP_CORK:
/* Ignore */
rv = 0;
break;
if (ldp->vcl_needs_real_epoll)
{
+ /* Make sure workers have been allocated */
+ if (!ldp->workers)
+ {
+ ldp_alloc_workers ();
+ ldpw = ldp_worker_get_current ();
+ }
rv = libc_epoll_create1 (flags);
ldp->vcl_needs_real_epoll = 0;
ldpw->vcl_mq_epfd = rv;
{
swrap_constructor ();
if (ldp_init () != 0)
- fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
- getpid ());
+ {
+ fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
+ getpid ());
+ _exit (1);
+ }
else if (LDP_DEBUG > 0)
clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
}