use a single format for all messages simplifying server

That patch also combines all the message generation or receiving
functions for to allow easier modifications to the format.
This commit is contained in:
Nikos Mavrogiannopoulos
2016-03-06 16:45:13 +01:00
parent 8a99ed78db
commit 8892eb1934
17 changed files with 256 additions and 326 deletions

View File

@@ -298,7 +298,7 @@ ssize_t recvmsg_timeout(int sockfd, struct msghdr * msg, int flags,
return ret;
}
int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout)
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout)
{
struct iovec iov[3];
char data[5];
@@ -306,10 +306,6 @@ int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsi
ssize_t left;
uint8_t rcmd;
struct msghdr hdr;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
int ret;
iov[0].iov_base = &rcmd;
@@ -322,9 +318,6 @@ int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsi
hdr.msg_iov = iov;
hdr.msg_iovlen = 2;
hdr.msg_control = control_un.control;
hdr.msg_controllen = sizeof(control_un.control);
ret = recvmsg_timeout(ifd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
@@ -384,11 +377,9 @@ int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsi
}
/* Sends message + socketfd */
static
int send_socket_msg(void *pool, int fd, uint8_t cmd,
int socketfd, const void *msg,
pack_size_func get_size, pack_func pack,
unsigned use_32bit)
pack_size_func get_size, pack_func pack)
{
struct iovec iov[3];
struct msghdr hdr;
@@ -398,7 +389,6 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
} control_un;
struct cmsghdr *cmptr;
void *packed = NULL;
uint16_t length16;
uint32_t length32;
size_t length = 0;
int ret;
@@ -411,21 +401,12 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
if (msg)
length = get_size(msg);
if (use_32bit) {
if (length >= UINT32_MAX)
return -1;
if (length >= UINT32_MAX)
return -1;
length32 = length;
iov[1].iov_base = &length32;
iov[1].iov_len = 4;
} else {
if (length >= UINT16_MAX)
return -1;
length16 = length;
iov[1].iov_base = &length16;
iov[1].iov_len = 2;
}
length32 = length;
iov[1].iov_base = &length32;
iov[1].iov_len = 4;
hdr.msg_iov = iov;
hdr.msg_iovlen = 2;
@@ -478,24 +459,129 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
return ret;
}
int send_socket_msg16(void *pool, int fd, uint8_t cmd,
int socketfd, const void *msg,
pack_size_func get_size, pack_func pack)
int recv_msg_headers(int fd, uint8_t *cmd, unsigned timeout)
{
return send_socket_msg(pool, fd, cmd, socketfd, msg, get_size, pack, 0);
struct iovec iov[3];
char buffer[5];
uint32_t l32;
struct msghdr hdr;
int ret;
iov[0].iov_base = buffer;
iov[0].iov_len = 5;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
hdr.msg_iovlen = 1;
ret = recvmsg_timeout(fd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
return -1;
}
if (ret == 0) {
syslog(LOG_ERR, "%s:%u: recvmsg returned zero", __FILE__,
__LINE__);
return -1;
}
*cmd = buffer[0];
memcpy(&l32, &buffer[1], 4);
return l32;
}
int send_socket_msg32(void *pool, int fd, uint8_t cmd,
int socketfd, const void *msg,
pack_size_func get_size, pack_func pack)
int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
int *received_fd)
{
return send_socket_msg(pool, fd, cmd, socketfd, msg, get_size, pack, 1);
struct iovec iov[3];
uint32_t l32;
struct msghdr hdr;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
int ret;
iov[0].iov_base = cmd;
iov[0].iov_len = 1;
iov[1].iov_base = &l32;
iov[1].iov_len = 4;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
hdr.msg_iovlen = 2;
hdr.msg_control = control_un.control;
hdr.msg_controllen = sizeof(control_un.control);
ret = recvmsg_timeout(fd, &hdr, 0, MAIN_SEC_MOD_TIMEOUT);
if (ret == -1) {
int e = errno;
syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
return -1;
}
if (ret == 0) {
syslog(LOG_ERR, "%s:%u: recvmsg returned zero", __FILE__,
__LINE__);
return -1;
}
/* try to receive socket (if any) */
if (received_fd != NULL) {
*received_fd = -1;
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL
&& cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET
|| cmptr->cmsg_type != SCM_RIGHTS) {
syslog(LOG_ERR,
"%s:%u: recvmsg returned invalid msg type",
__FILE__, __LINE__);
return ERR_BAD_COMMAND;
}
if (CMSG_DATA(cmptr))
memcpy(received_fd, CMSG_DATA(cmptr), sizeof(int));
}
}
if (l32 > data_size) {
syslog(LOG_ERR, "%s:%u: recv_msg_data: received more data than expected", __FILE__,
__LINE__);
ret = -1;
goto cleanup;
}
ret = force_read_timeout(fd, data, l32, MAIN_SEC_MOD_TIMEOUT);
if (ret < l32) {
int e = errno;
syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__,
__LINE__, strerror(e));
ret = -1;
goto cleanup;
}
ret = l32;
cleanup:
if (ret < 0 && received_fd != NULL && *received_fd != -1) {
close(*received_fd);
*received_fd = -1;
}
return ret;
}
static
int recv_socket_msg(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout, unsigned use_32bits)
unsigned timeout)
{
struct iovec iov[3];
uint32_t length;
@@ -514,11 +600,7 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
iov[0].iov_len = 1;
iov[1].iov_base = &length;
if (use_32bits) {
iov[1].iov_len = 4;
} else {
iov[1].iov_len = 2;
}
iov[1].iov_len = 4;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
@@ -547,12 +629,6 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
return ERR_BAD_COMMAND;
}
if (!use_32bits) {
uint16_t l16;
memcpy(&l16, &length, 2);
length = l16;
}
/* try to receive socket (if any) */
if (socketfd != NULL) {
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL
@@ -603,26 +679,14 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
cleanup:
talloc_free(data);
if (ret < 0 && socketfd != NULL && *socketfd != -1)
if (ret < 0 && socketfd != NULL && *socketfd != -1) {
close(*socketfd);
*socketfd = -1;
}
return ret;
}
int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
{
return recv_socket_msg(pool,fd, cmd, socketfd, msg, unpack, timeout, 0);
}
int recv_socket_msg32(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
{
return recv_socket_msg(pool,fd, cmd, socketfd, msg, unpack, timeout, 1);
}
void _talloc_free2(void *ctx, void *ptr)
{
talloc_free(ptr);

View File

@@ -54,49 +54,31 @@ typedef void* (*unpack_func)(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
int send_socket_msg16(void *pool, int fd, uint8_t cmd,
int send_socket_msg(void *pool, int fd, uint8_t cmd,
int socketfd,
const void* msg, pack_size_func get_size, pack_func pack);
int send_socket_msg32(void *pool, int fd, uint8_t cmd,
int socketfd,
const void* msg, pack_size_func get_size, pack_func pack);
int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout);
inline static int send_msg16(void *pool, int fd, uint8_t cmd,
const void *msg, pack_size_func get_size, pack_func pack)
{
return send_socket_msg16(pool, fd, cmd, -1, msg, get_size, pack);
}
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout);
inline static
int send_msg32(void *pool, int fd, uint8_t cmd,
int send_msg(void *pool, int fd, uint8_t cmd,
const void *msg, pack_size_func get_size, pack_func pack)
{
return send_socket_msg32(pool, fd, cmd, -1, msg, get_size, pack);
return send_socket_msg(pool, fd, cmd, -1, msg, get_size, pack);
}
int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
int recv_socket_msg(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
int recv_socket_msg32(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
/* the timeout is in seconds */
inline static int recv_msg16(void *pool, int fd, uint8_t cmd,
inline static int recv_msg(void *pool, int fd, uint8_t cmd,
void **msg, unpack_func unpack, unsigned timeout)
{
return recv_socket_msg16(pool, fd, cmd, NULL, msg, unpack, timeout);
}
inline static int recv_msg32(void *pool, int fd, uint8_t cmd,
void **msg, unpack_func unpack, unsigned timeout)
{
return recv_socket_msg32(pool, fd, cmd, NULL, msg, unpack, timeout);
return recv_socket_msg(pool, fd, cmd, NULL, msg, unpack, timeout);
}
int recv_msg_headers(int fd, uint8_t *cmd, unsigned timeout);
int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size, int *received_fd);
const char* cmd_request_to_str(unsigned cmd);
const char* discon_reason_to_str(unsigned reason);

View File

@@ -186,7 +186,7 @@ static void method_status(method_ctx *ctx, int cfd, uint8_t * msg,
rep.stored_tls_sessions = ctx->s->tlsdb_entries;
rep.banned_ips = main_ban_db_elems(ctx->s);
ret = send_msg32(ctx->pool, cfd, CTL_CMD_STATUS_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_STATUS_REP, &rep,
(pack_size_func) status_rep__get_packed_size,
(pack_func) status_rep__pack);
if (ret < 0) {
@@ -208,7 +208,7 @@ static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg,
rep.status = 1;
ret = send_msg32(ctx->pool, cfd, CTL_CMD_RELOAD_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_RELOAD_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
if (ret < 0) {
@@ -230,7 +230,7 @@ static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg,
rep.status = 1;
ret = send_msg32(ctx->pool, cfd, CTL_CMD_STOP_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_STOP_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
if (ret < 0) {
@@ -420,7 +420,7 @@ static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg,
}
}
ret = send_msg32(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
(pack_size_func) user_list_rep__get_packed_size,
(pack_func) user_list_rep__pack);
if (ret < 0) {
@@ -498,7 +498,7 @@ static void method_list_banned(method_ctx *ctx, int cfd, uint8_t * msg,
e = htable_next(db, &iter);
}
ret = send_msg32(ctx->pool, cfd, CTL_CMD_LIST_BANNED_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_BANNED_REP, &rep,
(pack_size_func) ban_list_rep__get_packed_size,
(pack_func) ban_list_rep__pack);
if (ret < 0) {
@@ -516,14 +516,14 @@ static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: list-cookies");
ret = send_msg16(ctx->pool, ctx->s->sec_mod_fd_sync, CMD_SECM_LIST_COOKIES,
ret = send_msg(ctx->pool, ctx->s->sec_mod_fd_sync, CMD_SECM_LIST_COOKIES,
NULL, NULL, NULL);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending list cookies to sec-mod!");
}
ret = forward_msg32(ctx->pool, ctx->s->sec_mod_fd_sync, CMD_SECM_LIST_COOKIES_REPLY,
cfd, CTL_CMD_LIST_COOKIES_REP, MAIN_SEC_MOD_TIMEOUT);
ret = forward_msg(ctx->pool, ctx->s->sec_mod_fd_sync, CMD_SECM_LIST_COOKIES_REPLY,
cfd, CTL_CMD_LIST_COOKIES_REP, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending list cookies reply");
}
@@ -575,7 +575,7 @@ static void single_info_common(method_ctx *ctx, int cfd, uint8_t * msg,
mslog(ctx->s, NULL, LOG_INFO, "could not find ID '%u'", id);
}
ret = send_msg32(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
(pack_size_func) user_list_rep__get_packed_size,
(pack_func) user_list_rep__pack);
if (ret < 0) {
@@ -647,7 +647,7 @@ static void method_unban_ip(method_ctx *ctx,
unban_req__free_unpacked(req, NULL);
ret = send_msg32(ctx->pool, cfd, CTL_CMD_UNBAN_IP_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_UNBAN_IP_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
if (ret < 0) {
@@ -686,7 +686,7 @@ static void method_disconnect_user_name(method_ctx *ctx,
username_req__free_unpacked(req, NULL);
ret = send_msg32(ctx->pool, cfd, CTL_CMD_DISCONNECT_NAME_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_NAME_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
if (ret < 0) {
@@ -726,7 +726,7 @@ static void method_disconnect_user_id(method_ctx *ctx, int cfd,
/* reply */
id_req__free_unpacked(req, NULL);
ret = send_msg32(ctx->pool, cfd, CTL_CMD_DISCONNECT_ID_REP, &rep,
ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_ID_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
if (ret < 0) {
@@ -745,9 +745,9 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
{
main_server_st *s = ev_userdata(loop);
int ret, e;
uint16_t length;
size_t length;
uint8_t cmd;
uint8_t buffer[256];
unsigned buffer_size;
method_ctx ctx;
struct ctl_watcher_st *wst = container_of(w, struct ctl_watcher_st, ctl_cmd_io);
unsigned i, indef = 0;
@@ -759,41 +759,24 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
goto fail;
/* read request */
ret = recv(wst->fd, buffer, sizeof(buffer), 0);
if (ret == 0)
goto fail;
if (ret < 3) {
if (ret == -1) {
e = errno;
mslog(s, NULL, LOG_ERR, "error receiving ctl data: %s",
strerror(e));
} else {
mslog(s, NULL, LOG_ERR, "received ctl data: %d bytes",
ret);
}
goto fail;
ret = recv_msg_data(wst->fd, &cmd, buffer, sizeof(buffer), NULL);
if (ret == -1) {
e = errno;
mslog(s, NULL, LOG_ERR, "error receiving ctl data: %s",
strerror(e));
}
memcpy(&length, &buffer[1], 2);
buffer_size = ret - 3;
if (length != buffer_size) {
mslog(s, NULL, LOG_ERR,
"received data length doesn't match received data (%d/%d)",
buffer_size, (int)length);
goto fail;
}
length = ret;
for (i = 0;; i++) {
if (methods[i].cmd == 0) {
mslog(s, NULL, LOG_INFO,
"unknown unix ctl message: 0x%.1x",
(unsigned)buffer[0]);
(unsigned)cmd);
break;
} else if (methods[i].cmd == buffer[0]) {
} else if (methods[i].cmd == cmd) {
indef = methods[i].indefinite;
methods[i].func(&ctx, wst->fd, buffer + 3, buffer_size);
methods[i].func(&ctx, wst->fd, buffer, length);
break;
}
}
@@ -901,7 +884,7 @@ void ctl_handler_notify (main_server_st* s, struct proc_st *proc, unsigned conne
}
rep.user = &list;
ret = send_msg32(pool, s->top_fd, CTL_CMD_TOP_UPDATE_REP, &rep,
ret = send_msg(pool, s->top_fd, CTL_CMD_TOP_UPDATE_REP, &rep,
(pack_size_func) top_update_rep__get_packed_size,
(pack_func) top_update_rep__pack);
if (ret < 0) {

View File

@@ -146,7 +146,7 @@ int handle_sec_mod_commands(main_server_st * s)
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_BAN_IP_REPLY));
ret = send_msg16(NULL, s->sec_mod_fd, CMD_SECM_BAN_IP_REPLY,
ret = send_msg(NULL, s->sec_mod_fd, CMD_SECM_BAN_IP_REPLY,
&reply, (pack_size_func)ban_ip_reply_msg__get_packed_size,
(pack_func)ban_ip_reply_msg__pack);
if (ret < 0) {
@@ -431,7 +431,7 @@ int session_open(main_server_st * s, struct proc_st *proc, const uint8_t *cookie
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_SESSION_OPEN));
ret = send_msg16(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_OPEN,
ret = send_msg(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_OPEN,
&ireq, (pack_size_func)secm_session_open_msg__get_packed_size,
(pack_func)secm_session_open_msg__pack);
if (ret < 0) {
@@ -440,7 +440,7 @@ int session_open(main_server_st * s, struct proc_st *proc, const uint8_t *cookie
return -1;
}
ret = recv_msg32(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_REPLY,
ret = recv_msg(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_REPLY,
(void *)&msg, (unpack_func) secm_session_reply_msg__unpack, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;
@@ -513,7 +513,7 @@ int session_close(main_server_st * s, struct proc_st *proc)
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_SESSION_CLOSE));
ret = send_msg16(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_CLOSE,
ret = send_msg(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_CLOSE,
&ireq, (pack_size_func)secm_session_close_msg__get_packed_size,
(pack_func)secm_session_close_msg__pack);
if (ret < 0) {
@@ -522,7 +522,7 @@ int session_close(main_server_st * s, struct proc_st *proc)
return -1;
}
ret = recv_msg32(proc, s->sec_mod_fd_sync, CMD_SECM_CLI_STATS,
ret = recv_msg(proc, s->sec_mod_fd_sync, CMD_SECM_CLI_STATS,
(void *)&msg, (unpack_func) cli_stats_msg__unpack, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;

View File

@@ -236,28 +236,14 @@ static int handle_cookie_auth_res(main_server_st *s, struct proc_st *proc,
int handle_worker_commands(main_server_st * s, struct proc_st *proc)
{
struct iovec iov[3];
uint8_t cmd;
struct msghdr hdr;
AuthCookieRequestMsg *auth_cookie_req;
uint16_t length;
size_t length;
uint8_t *raw;
int ret, raw_len, e;
PROTOBUF_ALLOCATOR(pa, proc);
iov[0].iov_base = &cmd;
iov[0].iov_len = 1;
iov[1].iov_base = &length;
iov[1].iov_len = 2;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
hdr.msg_iovlen = 2;
do {
ret = recvmsg(proc->fd, &hdr, 0);
} while (ret == -1 && errno == EINTR);
ret = recv_msg_headers(proc->fd, &cmd, MAX_WAIT_SECS);
if (ret == -1) {
e = errno;
mslog(s, proc, LOG_ERR,
@@ -266,15 +252,7 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
return ERR_BAD_COMMAND;
}
if (ret == 0) {
mslog(s, proc, LOG_DEBUG, "command socket closed");
return ERR_WORKER_TERMINATED;
}
if (ret < 3) {
mslog(s, proc, LOG_ERR, "command error");
return ERR_BAD_COMMAND;
}
length = ret;
mslog(s, proc, LOG_DEBUG, "main received message '%s' of %u bytes\n",
cmd_request_to_str(cmd), (unsigned)length);
@@ -285,7 +263,7 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
return ERR_MEM;
}
raw_len = force_read_timeout(proc->fd, raw, length, 2);
raw_len = force_read_timeout(proc->fd, raw, length, MAX_WAIT_SECS);
if (raw_len != length) {
e = errno;
mslog(s, proc, LOG_ERR,

View File

@@ -299,7 +299,7 @@ int send_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd,
const void* msg, pack_size_func get_size, pack_func pack)
{
mslog(s, proc, LOG_DEBUG, "sending message '%s' to worker", cmd_request_to_str(cmd));
return send_msg16(proc, proc->fd, cmd, msg, get_size, pack);
return send_msg(proc, proc->fd, cmd, msg, get_size, pack);
}
inline static
@@ -307,7 +307,7 @@ int send_socket_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t c
int socketfd, const void* msg, pack_size_func get_size, pack_func pack)
{
mslog(s, proc, LOG_DEBUG, "sending (socket) message %u to worker", (unsigned)cmd);
return send_socket_msg16(proc, proc->fd, cmd, socketfd, msg, get_size, pack);
return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size, pack);
}
void request_reload(int signo);

View File

@@ -94,42 +94,12 @@ int send_cmd(struct unix_ctx *ctx, unsigned cmd, const void *data,
pack_size_func get_size, pack_func pack,
struct cmd_reply_st *rep)
{
uint8_t header[3];
struct iovec iov[2];
unsigned iov_len = 1;
int e, ret;
uint16_t rlength = 0;
uint32_t length32 = 0;
void *packed = NULL;
uint8_t rcmd;
if (get_size)
rlength = get_size(data);
header[0] = cmd;
memcpy(&header[1], &rlength, 2);
iov[0].iov_base = header;
iov[0].iov_len = 3;
if (data != NULL) {
packed = talloc_size(ctx, rlength);
if (packed == NULL) {
fprintf(stderr, "memory error\n");
return -1;
}
iov[1].iov_base = packed;
iov[1].iov_len = rlength;
ret = pack(data, packed);
if (ret == 0) {
fprintf(stderr, "data packing error\n");
ret = -1;
goto fail;
}
iov_len++;
}
ret = writev(ctx->fd, iov, iov_len);
ret = send_msg(ctx, ctx->fd, cmd, data, get_size, pack);
if (ret < 0) {
e = errno;
fprintf(stderr, "writev: %s\n", strerror(e));
@@ -138,7 +108,7 @@ int send_cmd(struct unix_ctx *ctx, unsigned cmd, const void *data,
}
if (rep != NULL) {
ret = force_read_timeout(ctx->fd, header, 1+sizeof(length32), DEFAULT_TIMEOUT);
ret = recv_msg_headers(ctx->fd, &rcmd, DEFAULT_TIMEOUT);
if (ret == -1) {
/*e = errno;
fprintf(stderr, "read: %s\n", strerror(e));*/
@@ -146,13 +116,8 @@ int send_cmd(struct unix_ctx *ctx, unsigned cmd, const void *data,
goto fail;
}
if (ret != 1+sizeof(length32)) {
fprintf(stderr, "short read %d\n", ret);
ret = -1;
goto fail;
}
rep->cmd = header[0];
rep->cmd = rcmd;
length32 = ret;
if (msg_map[cmd] != rep->cmd) {
fprintf(stderr, "Unexpected message '%d', expected '%d'\n", (int)rep->cmd, (int)msg_map[cmd]);
@@ -160,8 +125,6 @@ int send_cmd(struct unix_ctx *ctx, unsigned cmd, const void *data,
goto fail;
}
memcpy(&length32, &header[1], 4);
rep->data_size = length32;
rep->data = talloc_size(ctx, length32);
if (rep->data == NULL) {

View File

@@ -93,7 +93,7 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e, const char *ip
return;
}
ret = send_msg32(lpool, sec->cmd_fd, CMD_SECM_BAN_IP, &msg,
ret = send_msg(lpool, sec->cmd_fd, CMD_SECM_BAN_IP, &msg,
(pack_size_func) ban_ip_msg__get_packed_size,
(pack_func) ban_ip_msg__pack);
if (ret < 0) {
@@ -132,7 +132,7 @@ int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTH
msg.dtls_session_id.data = entry->dtls_session_id;
msg.dtls_session_id.len = sizeof(entry->dtls_session_id);
ret = send_msg16(entry, cfd, CMD_SEC_AUTH_REPLY,
ret = send_msg(entry, cfd, CMD_SEC_AUTH_REPLY,
&msg,
(pack_size_func)
sec_auth_reply_msg__get_packed_size,
@@ -140,7 +140,7 @@ int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTH
} else {
msg.reply = AUTH__REP__FAILED;
ret = send_msg16(entry, cfd, CMD_SEC_AUTH_REPLY,
ret = send_msg(entry, cfd, CMD_SEC_AUTH_REPLY,
&msg,
(pack_size_func)
sec_auth_reply_msg__get_packed_size,
@@ -176,7 +176,7 @@ int send_sec_auth_reply_msg(int cfd, sec_mod_st * sec, client_entry_st * e)
msg.sid.data = e->sid;
msg.sid.len = sizeof(e->sid);
ret = send_msg16(e, cfd, CMD_SEC_AUTH_REPLY, &msg,
ret = send_msg(e, cfd, CMD_SEC_AUTH_REPLY, &msg,
(pack_size_func) sec_auth_reply_msg__get_packed_size,
(pack_func) sec_auth_reply_msg__pack);
if (ret < 0) {
@@ -343,7 +343,7 @@ int send_failed_session_open_reply(sec_mod_st *sec, int fd)
return ERR_BAD_COMMAND;
}
ret = send_msg32(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
ret = send_msg(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
if (ret < 0) {
@@ -439,7 +439,7 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
}
}
ret = send_msg32(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
ret = send_msg(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
if (ret < 0) {
@@ -472,14 +472,14 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
char tmp[BASE64_ENCODE_RAW_LENGTH(SID_SIZE) + 1];
oc_base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp));
seclog(sec, LOG_INFO, "session close but with non-existing SID: %s", tmp);
return send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
return send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
}
if (e->status < PS_AUTH_COMPLETED) {
seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.psid);
return send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
return send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
}
@@ -506,7 +506,7 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
rep.secmod_tlsdb_entries = sec->tls_db.entries;
rep.has_secmod_tlsdb_entries = 1;
ret = send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
ret = send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
if (ret < 0) {

View File

@@ -32,7 +32,7 @@ static void send_empty_reply(void *pool, int fd, sec_mod_st *sec)
SecmListCookiesReplyMsg msg = SECM_LIST_COOKIES_REPLY_MSG__INIT;
int ret;
ret = send_msg32(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
ret = send_msg(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
(pack_func) secm_list_cookies_reply_msg__pack);
if (ret < 0) {
@@ -54,6 +54,8 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
return;
}
seclog(sec, LOG_DEBUG, "sending list cookies reply to main");
msg.cookies = talloc_size(pool, sizeof(CookieIntMsg*)*db->elems);
if (msg.cookies == NULL) {
send_empty_reply(pool, fd, sec);
@@ -91,7 +93,7 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
t = htable_next(db, &iter);
}
ret = send_msg32(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
ret = send_msg(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
(pack_func) secm_list_cookies_reply_msg__pack);
if (ret < 0) {

View File

@@ -48,7 +48,6 @@
#include <gnutls/crypto.h>
#include <gnutls/abstract.h>
#define MAX_WAIT_SECS 3
#define MAX_PIN_SIZE GNUTLS_PKCS11_MAX_PIN_LEN
#define MAINTAINANCE_TIME 310
@@ -189,7 +188,7 @@ static int handle_op(void *pool, int cfd, sec_mod_st * sec, uint8_t type, uint8_
msg.data.data = rep;
msg.data.len = rep_size;
ret = send_msg16(pool, cfd, type, &msg,
ret = send_msg(pool, cfd, type, &msg,
(pack_size_func) sec_op_msg__get_packed_size,
(pack_func) sec_op_msg__pack);
if (ret < 0) {
@@ -386,7 +385,7 @@ int process_packet(void *pool, int cfd, pid_t pid, sec_mod_st * sec, cmd_request
}
ret =
send_msg16(pool, cfd, RESUME_FETCH_REP, &msg,
send_msg(pool, cfd, RESUME_FETCH_REP, &msg,
(pack_size_func)
session_resume_reply_msg__get_packed_size,
(pack_func)
@@ -538,15 +537,13 @@ static
int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer_size)
{
int ret, e;
unsigned cmd, length;
uint16_t l16;
uint8_t cmd;
size_t length;
void *pool = buffer;
/* read request */
ret = force_read_timeout(fd, buffer, 3, MAIN_SEC_MOD_TIMEOUT);
if (ret == 0)
goto leave;
else if (ret < 3) {
ret = recv_msg_headers(fd, &cmd, MAIN_SEC_MOD_TIMEOUT);
if (ret == -1) {
e = errno;
seclog(sec, LOG_ERR, "error receiving msg head: %s",
strerror(e));
@@ -554,9 +551,7 @@ int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer
goto leave;
}
cmd = buffer[0];
memcpy(&l16, &buffer[1], 2);
length = l16;
length = ret;
seclog(sec, LOG_DEBUG, "received request %s", cmd_request_to_str(cmd));
if (cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD) {
@@ -565,8 +560,8 @@ int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer
return ERR_BAD_COMMAND;
}
if (length > buffer_size - 4) {
seclog(sec, LOG_ERR, "received too big message (%d)", length);
if (length > buffer_size) {
seclog(sec, LOG_ERR, "received too big message (%d)", (int)length);
ret = ERR_BAD_COMMAND;
goto leave;
}
@@ -594,28 +589,24 @@ static
int serve_request_worker(sec_mod_st *sec, int cfd, pid_t pid, uint8_t *buffer, unsigned buffer_size)
{
int ret, e;
unsigned cmd, length;
uint16_t l16;
uint8_t cmd;
size_t length;
void *pool = buffer;
/* read request */
ret = force_read_timeout(cfd, buffer, 3, MAX_WAIT_SECS);
if (ret == 0)
goto leave;
else if (ret < 3) {
ret = recv_msg_headers(cfd, &cmd, MAX_WAIT_SECS);
if (ret == -1) {
e = errno;
seclog(sec, LOG_INFO, "error receiving msg head: %s",
seclog(sec, LOG_ERR, "error receiving msg head: %s",
strerror(e));
ret = -1;
ret = ERR_BAD_COMMAND;
goto leave;
}
cmd = buffer[0];
memcpy(&l16, &buffer[1], 2);
length = l16;
length = ret;
if (length > buffer_size - 4) {
seclog(sec, LOG_INFO, "too big message (%d)", length);
if (length > buffer_size) {
seclog(sec, LOG_INFO, "too big message (%d)", (int)length);
ret = -1;
goto leave;
}
@@ -746,8 +737,8 @@ static int load_keys(sec_mod_st *sec, unsigned force)
*
* The security module's reply to the worker has the
* following format:
* byte[0-1]: length (uint16_t)
* byte[2-total]: data (signature or decrypted data)
* byte[0-5]: length (uint32_t)
* byte[5-total]: data (signature or decrypted data)
*
* The reason for having this as a separate process
* is to avoid any bug on the workers to leak the key.

View File

@@ -636,14 +636,14 @@ int key_cb_common_func (gnutls_privkey_t key, void* userdata, const gnutls_datum
msg.data.data = raw_data->data;
msg.data.len = raw_data->size;
ret = send_msg16(userdata, sd, type, &msg,
ret = send_msg(userdata, sd, type, &msg,
(pack_size_func)sec_op_msg__get_packed_size,
(pack_func)sec_op_msg__pack);
if (ret < 0) {
goto error;
}
ret = recv_msg16(userdata, sd, type, (void*)&reply,
ret = recv_msg(userdata, sd, type, (void*)&reply,
(unpack_func)sec_op_msg__unpack,
DEFAULT_SOCKET_TIMEOUT);
if (ret < 0) {

View File

@@ -117,6 +117,7 @@ inline static const char *proto_to_str(fw_proto_t proto)
/* Timeout (secs) for communication between main and sec-mod */
#define MAIN_SEC_MOD_TIMEOUT 120
#define MAX_WAIT_SECS 3
#define DEBUG_BASIC 1
#define DEBUG_INFO 3

View File

@@ -532,7 +532,7 @@ static int recv_cookie_auth_reply(worker_st * ws)
AuthCookieReplyMsg *msg = NULL;
PROTOBUF_ALLOCATOR(pa, ws);
ret = recv_socket_msg16(ws, ws->cmd_fd, AUTH_COOKIE_REP, &socketfd,
ret = recv_socket_msg(ws, ws->cmd_fd, AUTH_COOKIE_REP, &socketfd,
(void *)&msg,
(unpack_func) auth_cookie_reply_msg__unpack,
DEFAULT_SOCKET_TIMEOUT);
@@ -673,7 +673,7 @@ static int recv_auth_reply(worker_st * ws, int sd, char **txt, unsigned *pcounte
SecAuthReplyMsg *msg = NULL;
PROTOBUF_ALLOCATOR(pa, ws);
ret = recv_msg16(ws, sd, CMD_SEC_AUTH_REPLY,
ret = recv_msg(ws, sd, CMD_SEC_AUTH_REPLY,
(void *)&msg, (unpack_func) sec_auth_reply_msg__unpack,
DEFAULT_SOCKET_TIMEOUT);
if (ret < 0) {

View File

@@ -79,42 +79,18 @@ static int recv_from_new_fd(struct worker_st *ws, int fd, UdpFdMsg *tmsg)
int handle_commands_from_main(struct worker_st *ws)
{
struct iovec iov[3];
uint8_t cmd;
uint16_t length;
int e;
struct msghdr hdr;
size_t length;
uint8_t cmd_data[1536];
int e;
UdpFdMsg *tmsg = NULL;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
int ret;
int fd = -1;
/*int cmd_data_len;*/
memset(&cmd_data, 0, sizeof(cmd_data));
iov[0].iov_base = &cmd;
iov[0].iov_len = 1;
iov[1].iov_base = &length;
iov[1].iov_len = 2;
iov[2].iov_base = cmd_data;
iov[2].iov_len = sizeof(cmd_data);
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
hdr.msg_iovlen = 3;
hdr.msg_control = control_un.control;
hdr.msg_controllen = sizeof(control_un.control);
do {
ret = recvmsg( ws->cmd_fd, &hdr, 0);
} while(ret == -1 && errno == EINTR);
ret = recv_msg_data(ws->cmd_fd, &cmd, cmd_data, sizeof(cmd_data), &fd);
if (ret == -1) {
e = errno;
oclog(ws, LOG_ERR, "cannot obtain data from command socket: %s", strerror(e));
@@ -126,12 +102,9 @@ int handle_commands_from_main(struct worker_st *ws)
return ERR_NO_CMD_FD;
}
if (length > ret - 3) {
oclog(ws, LOG_DEBUG, "worker received invalid message %s of %u bytes that claims to be %u\n", cmd_request_to_str(cmd), (unsigned)ret-3, (unsigned)length);
exit_worker(ws);
} else {
oclog(ws, LOG_DEBUG, "worker received message %s of %u bytes\n", cmd_request_to_str(cmd), (unsigned)length);
}
length = ret;
oclog(ws, LOG_DEBUG, "worker received message %s of %u bytes\n", cmd_request_to_str(cmd), (unsigned)length);
/*cmd_data_len = ret - 1;*/
@@ -140,7 +113,6 @@ int handle_commands_from_main(struct worker_st *ws)
exit_worker(ws);
case CMD_UDP_FD: {
unsigned has_hello = 1;
int fd;
if (ws->udp_state != UP_WAIT_FD) {
oclog(ws, LOG_DEBUG, "received another a UDP fd!");
@@ -151,44 +123,38 @@ int handle_commands_from_main(struct worker_st *ws)
has_hello = tmsg->hello;
}
if ( (cmptr = CMSG_FIRSTHDR(&hdr)) != NULL && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET || cmptr->cmsg_type != SCM_RIGHTS || CMSG_DATA(cmptr) == NULL) {
oclog(ws, LOG_ERR, "received UDP fd message of wrong type");
goto udp_fd_fail;
}
memcpy(&fd, CMSG_DATA(cmptr), sizeof(int));
set_non_block(fd);
if (has_hello == 0) {
/* check if the first packet received is a valid one -
* if not discard the new fd */
if (!recv_from_new_fd(ws, fd, tmsg)) {
oclog(ws, LOG_INFO, "received UDP fd message but its session has invalid data!");
if (tmsg)
udp_fd_msg__free_unpacked(tmsg, NULL);
close(fd);
return 0;
}
} else { /* received client hello */
ws->udp_state = UP_SETUP;
}
if (ws->dtls_tptr.fd != -1)
close(ws->dtls_tptr.fd);
if (tmsg && ws->dtls_tptr.msg != NULL)
udp_fd_msg__free_unpacked(ws->dtls_tptr.msg, NULL);
ws->dtls_tptr.msg = tmsg;
ws->dtls_tptr.fd = fd;
oclog(ws, LOG_DEBUG, "received new UDP fd and connected to peer");
return 0;
} else {
oclog(ws, LOG_ERR, "could not receive peer's UDP fd");
return -1;
if (fd == -1) {
oclog(ws, LOG_ERR, "received UDP fd message of wrong type");
goto udp_fd_fail;
}
set_non_block(fd);
if (has_hello == 0) {
/* check if the first packet received is a valid one -
* if not discard the new fd */
if (!recv_from_new_fd(ws, fd, tmsg)) {
oclog(ws, LOG_INFO, "received UDP fd message but its session has invalid data!");
if (tmsg)
udp_fd_msg__free_unpacked(tmsg, NULL);
close(fd);
return 0;
}
} else { /* received client hello */
ws->udp_state = UP_SETUP;
}
if (ws->dtls_tptr.fd != -1)
close(ws->dtls_tptr.fd);
if (tmsg && ws->dtls_tptr.msg != NULL)
udp_fd_msg__free_unpacked(ws->dtls_tptr.msg, NULL);
ws->dtls_tptr.msg = tmsg;
ws->dtls_tptr.fd = fd;
oclog(ws, LOG_DEBUG, "received new UDP fd and connected to peer");
return 0;
}
break;
default:

View File

@@ -46,7 +46,7 @@ static int recv_resume_fetch_reply(worker_st *ws, int sd, gnutls_datum_t *sdata)
SessionResumeReplyMsg *resp;
PROTOBUF_ALLOCATOR(pa, ws);
ret = recv_msg16(ws, sd, RESUME_FETCH_REP, (void*)&resp,
ret = recv_msg(ws, sd, RESUME_FETCH_REP, (void*)&resp,
(unpack_func)session_resume_reply_msg__unpack, DEFAULT_SOCKET_TIMEOUT);
if (ret < 0) {
oclog(ws, LOG_ERR, "error receiving resumption reply (fetch)");

View File

@@ -282,7 +282,7 @@ void ws_add_score_to_ip(worker_st *ws, unsigned points, unsigned final)
msg.ip = ws->remote_ip_str;
msg.score = points;
ret = send_msg16(ws, ws->cmd_fd, CMD_BAN_IP, &msg,
ret = send_msg(ws, ws->cmd_fd, CMD_BAN_IP, &msg,
(pack_size_func) ban_ip_msg__get_packed_size,
(pack_func) ban_ip_msg__pack);
if (ret < 0) {
@@ -294,7 +294,7 @@ void ws_add_score_to_ip(worker_st *ws, unsigned points, unsigned final)
if (final != 0)
return;
ret = recv_msg16(ws, ws->cmd_fd, CMD_BAN_IP_REPLY,
ret = recv_msg(ws, ws->cmd_fd, CMD_BAN_IP_REPLY,
(void *)&reply, (unpack_func) ban_ip_reply_msg__unpack, DEFAULT_SOCKET_TIMEOUT);
if (ret < 0) {
oclog(ws, LOG_ERR, "error receiving BAN IP reply message");

View File

@@ -346,7 +346,7 @@ int send_msg_to_secmod(worker_st * ws, int sd, uint8_t cmd,
oclog(ws, LOG_DEBUG, "sending message '%s' to secmod",
cmd_request_to_str(cmd));
return send_msg16(ws, sd, cmd, msg, get_size, pack);
return send_msg(ws, sd, cmd, msg, get_size, pack);
}
inline static
@@ -354,7 +354,7 @@ int send_msg_to_main(worker_st *ws, uint8_t cmd,
const void* msg, pack_size_func get_size, pack_func pack)
{
oclog(ws, LOG_DEBUG, "sending message '%s' to main", cmd_request_to_str(cmd));
return send_msg16(ws, ws->cmd_fd, cmd, msg, get_size, pack);
return send_msg(ws, ws->cmd_fd, cmd, msg, get_size, pack);
}
int parse_proxy_proto_header(struct worker_st *ws, int fd);