Close #48 增加从KNI读取KEYRING-ID的功能

This commit is contained in:
Lu Qiuwen
2018-10-19 19:50:27 +08:00
parent 8a0f3c8c3c
commit 213924e77e
7 changed files with 143 additions and 30 deletions

View File

@@ -22,22 +22,61 @@
#define TFE_CONFIG_KNI_UXDOMAIN_PATH_DEFAULT "/var/run/.tfe_kni_acceptor_handler"
#endif
/* The KNI and TFE communicate with each other by UNIX-based socket,
* and the protocol between them is based on TLV format(Type-Length-Value).
* The byte order for each entry in the protocol are Host-Ordered.
*
* I. Magic and Total counts of T-L-V tuples, at front of the SOCKET stream.
* II. After Magic header, the stream consist of several T-L-V tuples.
*
* Note. Magic = 0x4d5a
* Consider of the byte align problem, the minimum length of the value is 4bytes(32-bits).
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Magic | Total counts of TLV |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Value |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Value |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ....... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
enum
{
KNI_TLV_MAGIC = 0x4d5a
};
enum KNI_TLV_TYPE
{
KNI_TLV_TYPE_PRO = 0x01,
KNI_TLV_TYPE_PROTOCOL = 0x0001,
KNI_TLV_TYPE_KEYRING_ID = 0x0002
};
enum KNI_TLV_VALUE
{
KNI_TLV_VALUE_HTTP = 0x01,
KNI_TLV_VALUE_SSL = 0x02,
KNI_TLV_VALUE_HTTP = 0x1,
KNI_TLV_VALUE_SSL = 0x2,
};
struct kni_tlv_header
{
uint16_t magic;
uint16_t counts;
};
struct kni_tlv_info
{
char type;
short len;
char value;
uint16_t type;
uint16_t len;
uint8_t value[0];
};
struct kni_acceptor
@@ -70,6 +109,80 @@ void __kni_conn_close(struct kni_acceptor * ctx)
if (ctx->pid_kni_conn != 0) ctx->pid_kni_conn = 0;
}
static int __kni_parse_tlv_data(struct kni_acceptor * ctx,
struct tfe_proxy_accept_para * out_para, const char * data, size_t sz_data)
{
const char * __cursor = data;
size_t __left_data_len = sz_data;
/* Parse the STREAM header */
struct kni_tlv_header * tlv_header = (struct kni_tlv_header *)__cursor;
if (__left_data_len < sizeof(struct kni_tlv_header))
{
TFE_LOG_ERROR(ctx->logger, "Invalid KNI TLV header format, length is not enough.");
return -1;
}
if (tlv_header->magic != KNI_TLV_MAGIC)
{
TFE_LOG_ERROR(ctx->logger, "Invalid KNI TLV header magic number %x", tlv_header->magic);
return -2;
}
unsigned int nr_tlv_tuples = tlv_header->counts;
assert(nr_tlv_tuples != 0 && nr_tlv_tuples < 255);
__left_data_len -= sizeof(struct kni_tlv_header);
__cursor += sizeof(struct kni_tlv_header);
for(unsigned int iter_tlv_tuples = 0; iter_tlv_tuples < nr_tlv_tuples; iter_tlv_tuples++)
{
struct kni_tlv_info * tlv_info = (struct kni_tlv_info *) __cursor;
size_t sz_tlv_info = tlv_info->len + sizeof(struct kni_tlv_info);
if (__left_data_len < sz_tlv_info)
{
TFE_LOG_ERROR(ctx->logger, "TLV info declares invalid value length, Too long.");
return -3;
}
switch (tlv_info->type)
{
/* VALUE is uint32_t, length is 4 */
case KNI_TLV_TYPE_PROTOCOL:
{
uint32_t __value = *(uint32_t *)(tlv_info->value);
if(__value == KNI_TLV_VALUE_HTTP)
{
out_para->session_type = STREAM_PROTO_PLAIN;
}
if (__value == KNI_TLV_VALUE_SSL)
{
out_para->session_type = STREAM_PROTO_SSL;
}
assert(tlv_info->len == sizeof(uint32_t));
break;
}
/* VALUE is uint32_t, length is 4 */
case KNI_TLV_TYPE_KEYRING_ID:
{
uint32_t __value = *(uint32_t *)(tlv_info->value);
out_para->keyring_id = __value;
assert(tlv_info->len == sizeof(uint32_t));
break;
}
default: assert(0);
}
__cursor += sz_tlv_info;
__left_data_len -= sz_tlv_info;
}
return 0;
}
void __kni_event_cb(evutil_socket_t fd, short what, void * user)
{
struct kni_acceptor * __ctx = (struct kni_acceptor *)user;
@@ -89,12 +202,11 @@ void __kni_event_cb(evutil_socket_t fd, short what, void * user)
constexpr static int __CONTROLLEN = CMSG_SPACE(__TRANS_FDS_MAX * sizeof(int));
char __buffer[512] = {0};
struct kni_tlv_info * __tlv_info = (struct kni_tlv_info *)(__buffer);
struct iovec __iovec[1];
struct msghdr __msghdr;
char __cmptr[__CONTROLLEN];
__iovec[0].iov_base = __buffer;
__iovec[0].iov_len = sizeof(__buffer);
@@ -124,27 +236,13 @@ void __kni_event_cb(evutil_socket_t fd, short what, void * user)
__cmsghdr = CMSG_FIRSTHDR(&__msghdr);
__fds = (int *) (CMSG_DATA(__cmsghdr));
assert(__tlv_info->type == KNI_TLV_TYPE_PRO);
enum tfe_stream_proto __session_proto;
if (__tlv_info->value == KNI_TLV_VALUE_HTTP)
if(__kni_parse_tlv_data(__ctx, &__accept_para, __buffer, (size_t)rd) < 0)
{
__session_proto = STREAM_PROTO_PLAIN;
}
else if (__tlv_info->value == KNI_TLV_VALUE_SSL)
{
__session_proto = STREAM_PROTO_SSL;
}
else
{
assert(0);
goto __close_kni_connection;
}
__accept_para.session_type = __session_proto;
__accept_para.downstream_fd = __fds[0];
__accept_para.upstream_fd = __fds[1];
__accept_para.passthrough = false;
if (tfe_proxy_fds_accept(__ctx->proxy, &__accept_para) < 0)
{