Пример #1
0
/**
 * Close a session with the router, this is the mechanism
 * by which a router may cleanup data structure etc.
 *
 * @param instance		The router instance data
 * @param router_session	The session being closed
 */
static	void 	
closeSession(ROUTER *instance, void *router_session)
{
ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session;
DCB*              backend_dcb;

        CHK_CLIENT_RSES(router_cli_ses);
        /**
         * Lock router client session for secure read and update.
         */
        if (rses_begin_locked_router_action(router_cli_ses))
        {
		/* decrease server current connection counter */
		atomic_add(&router_cli_ses->backend->server->stats.n_current, -1);

                backend_dcb = router_cli_ses->backend_dcb;
                router_cli_ses->backend_dcb = NULL;
                router_cli_ses->rses_closed = true;
                /** Unlock */
                rses_end_locked_router_action(router_cli_ses);
                
                /**
                 * Close the backend server connection
                 */
                if (backend_dcb != NULL) {
                        CHK_DCB(backend_dcb);
                        dcb_close(backend_dcb);
                }
        }
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
/**
 * 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 The number of bytes sent
 */
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)
        {
                LOGIF(LT, (skygw_log_write(
                        LOGFILE_TRACE,
                        "Error : Failed to route MySQL command %d to backend "
                        "server.",
                        mysql_command)));
                goto return_rc;
        }
        
	switch(mysql_command) {
        case MYSQL_COM_CHANGE_USER:
                rc = backend_dcb->func.auth(
                        backend_dcb,
                        NULL,
                        backend_dcb->session,
                        queue);
		break;
        default:
                rc = backend_dcb->func.write(backend_dcb, queue);
                break;
        }
        
        CHK_PROTOCOL(((MySQLProtocol*)backend_dcb->protocol));
        LOGIF(LD, (skygw_log_write(
                LOGFILE_DEBUG,
                "%lu [readconnroute:routeQuery] Routed command %d to dcb %p "
                "with return value %d.",
                pthread_self(),
                mysql_command,
                backend_dcb,
                rc)));
return_rc:
        return rc;
}