Skip to content

Commit

Permalink
Change socket of states related operation to the state instead of ses…
Browse files Browse the repository at this point in the history
…sion
  • Loading branch information
MatheusNtg committed Aug 23, 2020
1 parent 66fce3c commit 2f27696
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 43 deletions.
108 changes: 84 additions & 24 deletions lib/lunatik.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ static int send_simple_control_msg(struct lunatik_session *session, int command,
return err;
}

static int send_fragment(struct lunatik_session *session, const char *original_script, int offset,
const char *state_name, const char *script_name, int flags)
static int send_fragment(struct lunatik_nl_state *state, const char *original_script, int offset,
const char *script_name, int flags)
{
struct nl_msg *msg;
char *fragment;
Expand All @@ -98,7 +98,7 @@ static int send_fragment(struct lunatik_session *session, const char *original_s
}
strncpy(fragment, original_script + (offset * LUNATIK_FRAGMENT_SIZE), LUNATIK_FRAGMENT_SIZE);

NLA_PUT_STRING(msg, STATE_NAME, state_name);
NLA_PUT_STRING(msg, STATE_NAME, state->name);
NLA_PUT_STRING(msg, CODE, fragment);

if (offset == 0)
Expand All @@ -109,7 +109,7 @@ static int send_fragment(struct lunatik_session *session, const char *original_s

NLA_PUT_U8(msg, FLAGS, flags);

if ((err = nl_send_auto(session->control_sock, msg)) < 0) {
if ((err = nl_send_auto(state->control_sock, msg)) < 0) {
printf("Failed to send fragment\n %s\n", nl_geterror(err));
nlmsg_free(msg);
return err;
Expand All @@ -125,7 +125,7 @@ static int send_fragment(struct lunatik_session *session, const char *original_s
return err;
}

static int receive_op_result(struct lunatik_session *session){
static int receive_session_op_result(struct lunatik_session *session){
int ret;

if ((ret = nl_recvmsgs_default(session->control_sock))) {
Expand All @@ -143,6 +143,24 @@ static int receive_op_result(struct lunatik_session *session){
return 0;
}

static int receive_state_op_result(struct lunatik_nl_state *state){
int ret;

if ((ret = nl_recvmsgs_default(state->control_sock))) {
printf("Failed to receive message from kernel: %s\n", nl_geterror(ret));
return ret;
}

nl_wait_for_ack(state->control_sock);

if (state->cb_result == CB_ERROR){
state->cb_result = CB_EMPTY_RESULT;
return -1;
}

return 0;
}

int init_recv_datasocket_on_kernel(struct lunatik_nl_state *state)
{
struct nl_msg *msg;
Expand Down Expand Up @@ -197,49 +215,49 @@ int lunatikS_newstate(struct lunatik_session *session, struct lunatik_nl_state *
return ret;
}

return receive_op_result(session);
return receive_session_op_result(session);

nla_put_failure:
printf("Failed to put attributes on message\n");
return ret;
}

int lunatikS_closestate(struct lunatik_nl_state *state)
int lunatik_closestate(struct lunatik_nl_state *state)
{
struct lunatik_session *session;
struct nl_msg *msg;
int ret = -1;

session = state->session;

if ((msg = prepare_message(DESTROY_STATE, 0)) == NULL)
return ret;

NLA_PUT_STRING(msg, STATE_NAME, state->name);

if ((ret = nl_send_auto(session->control_sock, msg)) < 0) {
printf("Failed to send destroy message:\n %s\n", nl_geterror(ret));
if ((ret = nl_send_auto(state->control_sock, msg)) < 0) {
printf("Failed to send destroy message:\n\t%s\n", nl_geterror(ret));
return ret;
}

ret = receive_state_op_result(state);

nl_socket_free(state->send_datasock);
nl_socket_free(state->recv_datasock);
nl_socket_free(state->control_sock);

return receive_op_result(session);
return ret;

nla_put_failure:
printf("Failed to put attributes on netlink message\n");
return ret;
}

int lunatikS_dostring(struct lunatik_session *session, const char *state_name,
int lunatik_dostring(struct lunatik_nl_state *state,
const char *script, const char *script_name, size_t total_code_size)
{
int err = -1;
int parts = 0;

if (total_code_size <= LUNATIK_FRAGMENT_SIZE) {
err = send_fragment(session, script, 0, state_name, script_name, LUNATIK_INIT | LUNATIK_DONE);
err = send_fragment(state, script, 0, script_name, LUNATIK_INIT | LUNATIK_DONE);
if (err)
return err;
} else {
Expand All @@ -249,22 +267,22 @@ int lunatikS_dostring(struct lunatik_session *session, const char *state_name,

for (int i = 0; i < parts - 1; i++) {
if (i == 0)
err = send_fragment(session, script, i, state_name, script_name, LUNATIK_INIT | LUNATIK_MULTI);
err = send_fragment(state, script, i, script_name, LUNATIK_INIT | LUNATIK_MULTI);
else
err = send_fragment(session, script, i, state_name, script_name, LUNATIK_MULTI);
err = send_fragment(state, script, i, script_name, LUNATIK_MULTI);

nl_wait_for_ack(session->control_sock);
nl_wait_for_ack(state->control_sock);

if (err)
return err;
}

err = send_fragment(session, script, parts - 1, state_name, script_name, LUNATIK_DONE);
err = send_fragment(state, script, parts - 1, script_name, LUNATIK_DONE);
if (err)
return err;
}

return receive_op_result(session);
return receive_state_op_result(state);
}

int lunatikS_list(struct lunatik_session *session)
Expand Down Expand Up @@ -446,7 +464,6 @@ static int response_handler(struct nl_msg *msg, void *arg)
{
case CREATE_STATE:
case DESTROY_STATE:
case EXECUTE_CODE:
if (attrs_tb[OP_SUCESS] && nla_get_u8(attrs_tb[OP_SUCESS])) {
session->cb_result = CB_SUCCESS;
} else if (attrs_tb[OP_ERROR] && nla_get_u8(attrs_tb[OP_ERROR])) {
Expand Down Expand Up @@ -510,6 +527,30 @@ static int response_handler(struct nl_msg *msg, void *arg)
return NL_OK;
}

static int response_state_handler(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *nh = nlmsg_hdr(msg);
struct genlmsghdr *gnlh = genlmsg_hdr(nh);
struct nlattr * attrs_tb[ATTRS_COUNT + 1];
struct lunatik_nl_state *state = (struct lunatik_nl_state *)arg;

if (nla_parse(attrs_tb, ATTRS_COUNT, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL))
{
printf("Error parsing attributes\n");
state->cb_result = CB_ERROR;
return NL_OK;
}

if (attrs_tb[OP_SUCESS] && nla_get_u8(attrs_tb[OP_SUCESS])) {
state->cb_result = CB_SUCCESS;
} else if (attrs_tb[OP_ERROR] && nla_get_u8(attrs_tb[OP_ERROR])) {
state->cb_result = CB_ERROR;
}

return NL_OK;
}

static int init_data_buffer(struct data_buffer *data_buffer, size_t size);

static int data_handler(struct nl_msg *msg, void *arg)
Expand Down Expand Up @@ -657,7 +698,7 @@ void release_data_buffer(struct data_buffer *data_buffer)
data_buffer->size = 0;
}

int lunatikS_receive(struct lunatik_nl_state *state)
int lunatik_receive(struct lunatik_nl_state *state)
{
int err = 0;

Expand All @@ -671,7 +712,7 @@ int lunatikS_receive(struct lunatik_nl_state *state)
return err;
}

int lunatikS_initdata(struct lunatik_nl_state *state)
static int lunatik_initdata(struct lunatik_nl_state *state)
{
int ret = 0;

Expand Down Expand Up @@ -712,7 +753,7 @@ struct lunatik_nl_state *lunatikS_getstate(struct lunatik_session *session, cons
return NULL;
}

if (receive_op_result(session))
if (receive_session_op_result(session))
return NULL;

if ((session->cb_result == CB_STATE_NOT_FOUND) || (session->cb_result == CB_ERROR)) {
Expand All @@ -726,3 +767,22 @@ struct lunatik_nl_state *lunatikS_getstate(struct lunatik_session *session, cons
printf("Failed to put attributes on netlink message\n");
return NULL;
}

int lunatik_initstate(struct lunatik_nl_state *state)
{
int err;

if ((err = lunatik_initdata(state))) {
return err;
}

if ((err = init_socket(&state->control_sock))) {
printf("Failed to initialize the control socket for state %s\n", state->name);
nl_socket_free(state->control_sock);
return err;
}

nl_socket_modify_cb(state->control_sock, NL_CB_MSG_IN, NL_CB_CUSTOM, response_state_handler, state);

return 0;
}
9 changes: 5 additions & 4 deletions lib/lunatik.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct lunatik_nl_state {
struct lunatik_session *session;
struct nl_sock *send_datasock;
struct nl_sock *recv_datasock;
struct nl_sock *control_sock;
struct data_buffer data_buffer;
enum callback_result cb_result;
uint32_t maxalloc;
Expand Down Expand Up @@ -94,16 +95,16 @@ void lunatikS_close(struct lunatik_session *session);

int lunatikS_newstate(struct lunatik_session *session, struct lunatik_nl_state *s);

int lunatikS_closestate(struct lunatik_nl_state *state);
int lunatik_closestate(struct lunatik_nl_state *state);

int lunatikS_dostring(struct lunatik_session *session, const char *state_name,
int lunatik_dostring(struct lunatik_nl_state *state,
const char *script, const char *script_name, size_t total_code_size);

int lunatikS_list(struct lunatik_session *session);

int lunatikS_receive(struct lunatik_nl_state *state);
int lunatik_receive(struct lunatik_nl_state *state);

int lunatikS_initdata(struct lunatik_nl_state *state);
int lunatik_initstate(struct lunatik_nl_state *state);

struct lunatik_nl_state *lunatikS_getstate(struct lunatik_session *session, const char *name);

Expand Down
16 changes: 7 additions & 9 deletions lib/lunatik_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ static int lsession_newstate(lua_State *L)
return 2;
}

if (lunatikS_initdata(state)) {
lua_pushnil(L);
if (lunatik_initstate(state)) {
pusherrmsg(L, "Failed to initialize state\n");
return 1;
}

Expand All @@ -154,7 +154,7 @@ static int lsession_newstate(lua_State *L)
static int lstate_close(lua_State *L)
{
struct lunatik_nl_state *state = getnlstate(L);
if (lunatikS_closestate(state)){
if (lunatik_closestate(state)){
lua_pushnil(L);
return 1;
}
Expand All @@ -166,8 +166,6 @@ static int lstate_close(lua_State *L)
static int lstate_dostring(lua_State *L)
{
struct lunatik_nl_state *s = getnlstate(L);
struct lunatik_session *session = s->session;
const char *name = s->name;
size_t len;
const char *payload = luaL_checklstring(L, 2, &len);
const char *script_name = luaL_optstring(L, 3, "Lunatik");
Expand All @@ -176,7 +174,7 @@ static int lstate_dostring(lua_State *L)
printf("script name too long\n");
goto error;
}
int status = lunatikS_dostring(session, name, payload, script_name, len);
int status = lunatik_dostring(s, payload, script_name, len);

if (status)
goto error;
Expand Down Expand Up @@ -243,8 +241,8 @@ static int lsession_getstate(lua_State *L)

*state = *received_state;

if (lunatikS_initdata(state)) {
lua_pushnil(L);
if (lunatik_initstate(state)) {
pusherrmsg(L, "Failed to initialize the state\n");
return 1;
}

Expand Down Expand Up @@ -292,7 +290,7 @@ static int lstate_datareceive(lua_State *L)
struct lunatik_nl_state *state = getnlstate(L);
char *memory;

if (lunatikS_receive(state))
if (lunatik_receive(state))
goto error;

memory = luamem_newalloc(L, state->data_buffer.size);
Expand Down
14 changes: 14 additions & 0 deletions lib/tests/close.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,17 @@ assert(s1 ~= nil)

local err = s1:close()
assert(err ~= nil)

-- Using state after close session
s1 = session:new's1'
assert(s1 ~= nil)

session:close()
assert(s1:getname() == 's1')

err = s1:close()
assert(err)

-- Trying to close nonexistent state
err = s1:close()
assert(err == nil)
1 change: 1 addition & 0 deletions lunatik.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ typedef struct lunatik_state {
size_t maxalloc;
size_t curralloc;
size_t scriptsize;
bool inuse;
unsigned char name[LUNATIK_NAME_MAXSIZE];
} lunatik_State;

Expand Down
24 changes: 18 additions & 6 deletions netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,20 @@ static int lunatikN_newstate(struct sk_buff *buff, struct genl_info *info)

s = lunatik_netnewstate(state_name, *max_alloc, genl_info_net(info));

if (s == NULL) {
reply_with(OP_ERROR, CREATE_STATE, info);
} else {
s->instance = *instance;
reply_with(OP_SUCESS, CREATE_STATE, info);
}
if (s == NULL)
goto error;

if (s->inuse)
goto error;

s->instance = *instance;
reply_with(OP_SUCESS, CREATE_STATE, info);

return 0;

error:
reply_with(OP_ERROR, CREATE_STATE, info);
return 0;
}

static void init_codebuffer(lunatik_State *s, struct genl_info *info)
Expand Down Expand Up @@ -627,6 +633,12 @@ static int lunatikN_sendstate(struct sk_buff *buff, struct genl_info *info)
return 0;
}

if (state->inuse) {
pr_info("State %s is already in use\n", state_name);
reply_with(OP_ERROR, GET_STATE, info);
return 0;
}

if (sendstate_msg(state, info)) {
pr_err("Failed to send message to user space\n");
reply_with(OP_ERROR, GET_STATE, info);
Expand Down

0 comments on commit 2f27696

Please sign in to comment.