예제 #1
0
static int proxy_queue_reset(lua_State *L) {
	/* we expect 2 parameters */
	GQueue *q = *(GQueue **)luaL_checkself(L);

	network_injection_queue_reset(q);
    
	return 0;
}
/**
 * reseting a used and empty queue 
 */
void t_network_injection_queue_reset() {
	network_injection_queue *q;

	q = network_injection_queue_new();
	g_assert(q);

	/* add something to the queue and check if resetting works */
	g_assert_cmpint(0, ==, network_injection_queue_len(q));
	network_injection_queue_append(q, injection_new(1, NULL));
	g_assert_cmpint(1, ==, network_injection_queue_len(q));
	network_injection_queue_reset(q);
	g_assert_cmpint(0, ==, network_injection_queue_len(q));

	/* reset a empty queue */
	network_injection_queue_reset(q);
	g_assert_cmpint(0, ==, network_injection_queue_len(q));

	network_injection_queue_reset(q);
	g_assert_cmpint(0, ==, network_injection_queue_len(q));

	network_injection_queue_free(q);
}
예제 #3
0
static network_mysqld_lua_stmt_ret master_lua_read_query(network_mysqld_con *con) {
    network_mysqld_con_lua_t *st = con->plugin_con_state;
    char command = -1;
    network_socket *recv_sock = con->client;
    GList   *chunk  = recv_sock->recv_queue->chunks->head;
    GString *packet = chunk->data;

    if (packet->len < NET_HEADER_SIZE) return PROXY_SEND_QUERY; /* packet too short */

    command = packet->str[NET_HEADER_SIZE + 0];

    if (COM_QUERY == command) {
        /* we need some more data after the COM_QUERY */
        if (packet->len < NET_HEADER_SIZE + 2) return PROXY_SEND_QUERY;

        /* LOAD DATA INFILE is nasty */
        if (packet->len - NET_HEADER_SIZE - 1 >= sizeof("LOAD ") - 1 &&
                0 == g_ascii_strncasecmp(packet->str + NET_HEADER_SIZE + 1, C("LOAD "))) return PROXY_SEND_QUERY;
    }

    /* reset the query status */
    network_injection_queue_reset(st->injected.queries);

    /* ok, here we go */

#ifdef HAVE_LUA_H
    switch(network_mysqld_con_lua_register_callback(con, con->config->lua_script)) {
    case REGISTER_CALLBACK_SUCCESS:
        break;
    case REGISTER_CALLBACK_LOAD_FAILED:
        network_mysqld_con_send_error(con->client, C("MySQL Proxy Lua script failed to load. Check the error log."));
        con->state = CON_STATE_SEND_ERROR;
        return PROXY_SEND_RESULT;
    case REGISTER_CALLBACK_EXECUTE_FAILED:
        network_mysqld_con_send_error(con->client, C("MySQL Proxy Lua script failed to execute. Check the error log."));
        con->state = CON_STATE_SEND_ERROR;
        return PROXY_SEND_RESULT;
    }

    if (st->L) {
        lua_State *L = st->L;
        network_mysqld_lua_stmt_ret ret = PROXY_NO_DECISION;

        g_assert(lua_isfunction(L, -1));
        lua_getfenv(L, -1);
        g_assert(lua_istable(L, -1));

        /**
         * reset proxy.response to a empty table
         */
        lua_getfield(L, -1, "proxy");
        g_assert(lua_istable(L, -1));

        lua_newtable(L);
        lua_setfield(L, -2, "response");

        lua_pop(L, 1);

        /**
         * get the call back
         */
        lua_getfield_literal(L, -1, C("read_query"));
        if (lua_isfunction(L, -1)) {

            /* pass the packet as parameter */
            lua_pushlstring(L, packet->str + NET_HEADER_SIZE, packet->len - NET_HEADER_SIZE);

            if (lua_pcall(L, 1, 1, 0) != 0) {
                /* hmm, the query failed */
                g_critical("(read_query) %s", lua_tostring(L, -1));

                lua_pop(L, 2); /* fenv + errmsg */

                /* perhaps we should clean up ?*/

                return PROXY_SEND_QUERY;
            } else {
                if (lua_isnumber(L, -1)) {
                    ret = lua_tonumber(L, -1);
                }
                lua_pop(L, 1);
            }

            switch (ret) {
            case PROXY_SEND_RESULT:
                /* check the proxy.response table for content,
                 *
                 */


                if (network_mysqld_con_lua_handle_proxy_response(con, con->config->lua_script)) {
                    /**
                     * handling proxy.response failed
                     *
                     * send a ERR packet
                     */

                    network_mysqld_con_send_error(con->client, C("(lua) handling proxy.response failed, check error-log"));
                }

                break;
            case PROXY_NO_DECISION:
                /**
                 * PROXY_NO_DECISION and PROXY_SEND_QUERY may pick another backend
                 */
                break;
            case PROXY_SEND_QUERY:
                /* send the injected queries
                 *
                 * injection_new(..., query);
                 *
                 *  */

                if (st->injected.queries->length) {
                    ret = PROXY_SEND_INJECTION;
                }

                break;
            default:
                break;
            }
            lua_pop(L, 1); /* fenv */
        } else {
            lua_pop(L, 2); /* fenv + nil */
        }

        g_assert(lua_isfunction(L, -1));

        if (ret != PROXY_NO_DECISION) {
            return ret;
        }
    } else {
        network_mysqld_con_handle_stmt(NULL, con, packet);
        return PROXY_SEND_RESULT;
    }
#endif
    return PROXY_NO_DECISION;
}