コード例 #1
0
ファイル: testmodutil.c プロジェクト: jhnwkmn/MaxScale
int
test2()
{
GWBUF   *buffer;
char len = 128;
char query[129];

        buffer = gwbuf_alloc(132);
	ss_info_dassert((buffer != NULL),"Buffer should not be null");

	memset(query,';',128);
    memset(query+128,'\0',1);
	*((unsigned char*)buffer->start) = len;
	*((unsigned char*)buffer->start+1) = 0;
	*((unsigned char*)buffer->start+2) = 0;
	*((unsigned char*)buffer->start+3) = 1;
	*((unsigned char*)buffer->start+4) = 0x03;
	memcpy(buffer->start + 5,query,strlen(query));
	char* result = modutil_get_SQL(buffer);
	ss_dassert(strcmp(result,query) == 0);
	gwbuf_free(buffer);
	free(result);
        ss_dfprintf(stderr, "\t..done\n");
	return 0;

}
コード例 #2
0
ファイル: slavelag.c プロジェクト: jhnwkmn/MaxScale
/**
 * The routeQuery entry point. This is passed the query buffer
 * to which the filter should be applied. Once applied the
 * query should normally be passed to the downstream component
 * (filter or router) in the filter chain.
 *
 * If the regular expressed configured in the match parameter of the
 * filter definition matches the SQL text then add the hint
 * "Route to named server" with the name defined in the server parameter
 *
 * @param instance	The filter instance data
 * @param session	The filter session
 * @param queue		The query data
 */
static	int	
routeQuery(FILTER *instance, void *session, GWBUF *queue)
{
LAG_INSTANCE	*my_instance = (LAG_INSTANCE *)instance;
LAG_SESSION	*my_session = (LAG_SESSION *)session;
char			*sql;
time_t now = time(NULL);

	if (modutil_is_SQL(queue))
	{
	    if (queue->next != NULL)
	    {
		queue = gwbuf_make_contiguous(queue);
	    }

	    if(!query_is_parsed(queue))
	    {
		parse_query(queue);
	    }

	    if(query_classifier_get_operation(queue) & (QUERY_OP_DELETE|QUERY_OP_INSERT|QUERY_OP_UPDATE))
	    {
		if((sql = modutil_get_SQL(queue)) != NULL)
		{
		    if(my_instance->nomatch == NULL||(my_instance->nomatch && regexec(&my_instance->nore,sql,0,NULL,0) != 0))
		    {
			if(my_instance->match == NULL||
			 (my_instance->match && regexec(&my_instance->re,sql,0,NULL,0) == 0))
			{
			    my_session->hints_left = my_instance->count;
			    my_session->last_modification = now;
			    my_instance->stats.n_modified++;
			}
		    }
		    free(sql);
		}
	    }
	    else if(my_session->hints_left > 0)
	    {
		queue->hint = hint_create_route(queue->hint,
					 HINT_ROUTE_TO_MASTER,
					 NULL);
		my_session->hints_left--;
		my_instance->stats.n_add_count++;
	    }
	    else if(difftime(now,my_session->last_modification) < my_instance->time)
	    {
		queue->hint = hint_create_route(queue->hint,
					 HINT_ROUTE_TO_MASTER,
					 NULL);
		my_instance->stats.n_add_time++;
	    }
	}
	return my_session->down.routeQuery(my_session->down.instance,
			my_session->down.session, queue);
}
コード例 #3
0
ファイル: tee.c プロジェクト: jhnwkmn/MaxScale
/**
 *
 * @param my_instance
 * @param my_session
 * @param buffer
 * @return
 */
GWBUF* clone_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* buffer)
{
    GWBUF* clone = NULL;
    int length, residual = 0;
    char* ptr;
    
	if (my_session->branch_session &&
		my_session->branch_session->state == SESSION_STATE_ROUTER_READY)
	{
		if (my_session->residual)
		{
			clone = gwbuf_clone_all(buffer);

			if (my_session->residual < GWBUF_LENGTH(clone))
			{
				GWBUF_RTRIM(clone, GWBUF_LENGTH(clone) - residual);
			}
			my_session->residual -= GWBUF_LENGTH(clone);

			if (my_session->residual < 0)
			{
				my_session->residual = 0;
			}
		}
		else if (my_session->active && (ptr = modutil_get_SQL(buffer)) != NULL)
		{
			if ((my_instance->match == NULL ||
					regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
				(my_instance->nomatch == NULL ||
					regexec(&my_instance->nore,ptr,0,NULL, 0) != 0))
			{
				length = modutil_MySQL_query_len(buffer, &residual);
				clone = gwbuf_clone_all(buffer);
				my_session->residual = residual;
			}
			free(ptr);
		}
		else if (packet_is_required(buffer))
		{
			clone = gwbuf_clone_all(buffer);
		}
	}
    return clone;
}
コード例 #4
0
ファイル: qlafilter.c プロジェクト: littleyang/MaxScale
/**
 * The routeQuery entry point. This is passed the query buffer
 * to which the filter should be applied. Once applied the
 * query should normally be passed to the downstream component
 * (filter or router) in the filter chain.
 *
 * @param instance	The filter instance data
 * @param session	The filter session
 * @param queue		The query data
 */
static	int	
routeQuery(FILTER *instance, void *session, GWBUF *queue)
{
QLA_INSTANCE	*my_instance = (QLA_INSTANCE *)instance;
QLA_SESSION	*my_session = (QLA_SESSION *)session;
char		*ptr;
int		length = 0;
struct tm	t;
struct timeval	tv;

	if (my_session->active)
	{
		if (queue->next != NULL)
		{
			queue = gwbuf_make_contiguous(queue);
		}
		if ((ptr = modutil_get_SQL(queue)) != NULL)
		{
			if ((my_instance->match == NULL ||
				regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
				(my_instance->nomatch == NULL ||
					regexec(&my_instance->nore,ptr,0,NULL, 0) != 0))
			{
				gettimeofday(&tv, NULL);
				localtime_r(&tv.tv_sec, &t);
				fprintf(my_session->fp,
					"%02d:%02d:%02d.%-3d %d/%02d/%d, ",
					t.tm_hour, t.tm_min, t.tm_sec, (int)(tv.tv_usec / 1000),
					t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year);
				fprintf(my_session->fp,"%s\n",ptr);
				
			}
			free(ptr);
		}
	}
	/* Pass the query downstream */
	return my_session->down.routeQuery(my_session->down.instance,
			my_session->down.session, queue);
}
コード例 #5
0
ファイル: topfilter.c プロジェクト: DBMSRmutl/MaxScale
/**
 * The routeQuery entry point. This is passed the query buffer
 * to which the filter should be applied. Once applied the
 * query should normally be passed to the downstream component
 * (filter or router) in the filter chain.
 *
 * @param instance  The filter instance data
 * @param session   The filter session
 * @param queue     The query data
 */
static int
routeQuery(FILTER *instance, void *session, GWBUF *queue)
{
    TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance;
    TOPN_SESSION *my_session = (TOPN_SESSION *) session;
    char *ptr;

    if (my_session->active)
    {
        if (queue->next != NULL)
        {
            queue = gwbuf_make_contiguous(queue);
        }
        if ((ptr = modutil_get_SQL(queue)) != NULL)
        {
            if ((my_instance->match == NULL ||
                 regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
                (my_instance->exclude == NULL ||
                 regexec(&my_instance->exre, ptr, 0, NULL, 0) != 0))
            {
                my_session->n_statements++;
                if (my_session->current)
                {
                    free(my_session->current);
                }
                gettimeofday(&my_session->start, NULL);
                my_session->current = ptr;
            }
            else
            {
                free(ptr);
            }
        }
    }
    /* Pass the query downstream */
    return my_session->down.routeQuery(my_session->down.instance,
                                       my_session->down.session, queue);
}
コード例 #6
0
ファイル: readconnroute.c プロジェクト: jeffraska/MaxScale
/**
 * We have data from the client, we must route it to the backend.
 * This is simply a case of sending it to the connection that was
 * chosen when we started the client session.
 *
 * @param instance		The router instance
 * @param router_session	The router session returned from the newSession call
 * @param queue			The queue of data buffers to route
 * @return if succeed 1, otherwise 0
 */
static	int	
routeQuery(ROUTER *instance, void *router_session, GWBUF *queue)
{
        ROUTER_INSTANCE	  *inst = (ROUTER_INSTANCE *)instance;
        ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session;
        uint8_t           *payload = GWBUF_DATA(queue);
        int               mysql_command;
        int               rc;
        DCB*              backend_dcb;
        bool              rses_is_closed;
       
	inst->stats.n_queries++;
	mysql_command = MYSQL_GET_COMMAND(payload);

        /** Dirty read for quick check if router is closed. */
        if (router_cli_ses->rses_closed)
        {
                rses_is_closed = true;
        }
        else
        {
                /**
                 * Lock router client session for secure read of DCBs
                 */
                rses_is_closed = !(rses_begin_locked_router_action(router_cli_ses));
        }

        if (!rses_is_closed)
        {
                backend_dcb = router_cli_ses->backend_dcb;           
                /** unlock */
                rses_end_locked_router_action(router_cli_ses);
        }

        if (rses_is_closed ||  backend_dcb == NULL ||
            SERVER_IS_DOWN(router_cli_ses->backend->server))
        {
                LOGIF(LT, (skygw_log_write(
                        LOGFILE_TRACE|LOGFILE_ERROR,
                        "Error : Failed to route MySQL command %d to backend "
                        "server.%s",
                        mysql_command,rses_is_closed ? " Session is closed." : "")));
		rc = 0;
                goto return_rc;

        }

	char* trc = NULL;

        switch(mysql_command) {
		case MYSQL_COM_CHANGE_USER:
			rc = backend_dcb->func.auth(
				backend_dcb,
				NULL,
				backend_dcb->session,
				queue);
			break;
		case MYSQL_COM_QUERY:
			LOGIF(LOGFILE_TRACE,(trc = modutil_get_SQL(queue)));
		default:
			rc = backend_dcb->func.write(backend_dcb, queue);
			break;
        }

	LOGIF(LOGFILE_TRACE,skygw_log_write(
                LOGFILE_DEBUG|LOGFILE_TRACE,
		 "Routed [%s] to '%s'%s%s",
		 STRPACKETTYPE(mysql_command),
		 backend_dcb->server->unique_name,
		 trc?": ":".",
		 trc?trc:""));
	free(trc);
return_rc:
        return rc;
}
コード例 #7
0
ファイル: luafilter.c プロジェクト: bigshuai/MaxScale
/**
 * The routeQuery entry point. This is passed the query buffer
 * to which the filter should be applied. Once processed the
 * query is passed to the downstream component
 * (filter or router) in the filter chain.
 *
 * The Luafilter calls the routeQuery functions of both the session and the global script.
 * The query is passed as a string parameter to the routeQuery Lua function and
 * the return values of the session specific function, if any were returned,
 * are interpreted. If the first value is bool, it is interpreted as a decision
 * whether to route the query or to send an error packet to the client.
 * If it is a string, the current query is replaced with the return value and
 * the query will be routed. If nil is returned, the query is routed normally.
 *
 * @param instance	The filter instance data
 * @param session	The filter session
 * @param queue		The query data
 */
static int routeQuery(FILTER *instance, void *session, GWBUF *queue)
{
    LUA_SESSION *my_session = (LUA_SESSION *) session;
    LUA_INSTANCE *my_instance = (LUA_INSTANCE *) instance;
    DCB* dcb = my_session->session->client_dcb;
    char *fullquery = NULL, *ptr;
    bool route = true;
    GWBUF* forward = queue;
    int rc = 0;

    if (modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue))
    {
        fullquery = modutil_get_SQL(queue);

        if (fullquery && my_session->lua_state)
        {
            spinlock_acquire(&my_session->lock);
            lua_getglobal(my_session->lua_state, "routeQuery");
            lua_pushlstring(my_session->lua_state, fullquery, strlen(fullquery));
            if (lua_pcall(my_session->lua_state, 1, 1, 0))
            {
                MXS_ERROR("luafilter: Session scope call to 'routeQuery' failed: '%s'.",
                          lua_tostring(my_session->lua_state, -1));
            }
            else if (lua_gettop(my_session->lua_state))
            {
                if (lua_isstring(my_session->lua_state, -1))
                {
                    if (forward)
                    {
                        gwbuf_free(forward);
                    }
                    forward = modutil_create_query((char*) lua_tostring(my_session->lua_state, -1));
                }
                else if (lua_isboolean(my_session->lua_state, -1))
                {
                    route = lua_toboolean(my_session->lua_state, -1);
                }
            }
            spinlock_release(&my_session->lock);
        }

        if (my_instance->global_lua_state)
        {
            spinlock_acquire(&my_instance->lock);
            lua_getglobal(my_instance->global_lua_state, "routeQuery");
            lua_pushlstring(my_instance->global_lua_state, fullquery, strlen(fullquery));
            if (lua_pcall(my_instance->global_lua_state, 1, 0, 0))
            {
                MXS_ERROR("luafilter: Global scope call to 'routeQuery' failed: '%s'.",
                          lua_tostring(my_session->lua_state, -1));
            }
            else if (lua_gettop(my_instance->global_lua_state))
            {
                if (lua_isstring(my_instance->global_lua_state, -1))
                {
                    if (forward)
                    {
                        gwbuf_free(forward);
                    }
                    forward = modutil_create_query((char*)
                                                   lua_tostring(my_instance->global_lua_state, -1));
                }
                else if (lua_isboolean(my_instance->global_lua_state, -1))
                {
                    route = lua_toboolean(my_instance->global_lua_state, -1);
                }
            }
            spinlock_release(&my_instance->lock);
        }

        free(fullquery);
    }

    if (!route)
    {
        gwbuf_free(queue);
        GWBUF* err = modutil_create_mysql_err_msg(1, 0, 1045, "28000", "Access denied.");
        rc = dcb->func.write(dcb, err);
    }
    else
    {
        rc = my_session->down.routeQuery(my_session->down.instance,
                                         my_session->down.session, forward);
    }

    return rc;
}