/** * call the python function to intercept the handshake packet * * @return PROXY_SEND_QUERY to send the packet from the client * PROXY_NO_DECISION to pass the server packet unmodified */ static network_mysqld_python_stmt_ret proxy_python_read_handshake(network_mysqld_con *con) { network_mysqld_con_python_t *st = con->plugin_con_state; network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION; if(!CHECK_FUNC(read_handshake)) return ret; PyObject *result = PyObject_CallFunctionObjArgs( GET_FUNC(read_handshake), st->proxy, NULL); GET_PYTHON_RESULT(read_handshake) switch(ret) { case PROXY_NO_DECISION: break; case PROXY_SEND_QUERY: g_warning("%s.%d: (read_handshake) return proxy.PROXY_SEND_QUERY is " "deprecated, use PROXY_SEND_RESULT instead", __FILE__, __LINE__); ret = PROXY_SEND_RESULT; case PROXY_SEND_RESULT: if(network_mysqld_con_python_handle_proxy_response(con, st->proxy)) network_mysqld_con_send_error(con->client, C("(python) handling " "proxy.response failed, check error-log")); break; default: ret = PROXY_NO_DECISION; break; } return ret; }
int Get_F (node* tree) { int err_index = 0; ASSERT_TREE_OK (tree); char tmp_word[TMPLEN] = {}; strcpy (tmp_word, (*CUR) -> word); strupr (tmp_word); int func = 0; if (0); CHECK_FUNC(tmp_word, SIN) CHECK_FUNC(tmp_word, COS) CHECK_FUNC(tmp_word, TAN) CHECK_FUNC(tmp_word, CTAN) CHECK_FUNC(tmp_word, LN) CHECK_FUNC(tmp_word, LOG) if (func == 0) return ERR_WRONG_FUNC; CUR++; if ((*CUR) -> op != SEP_OPEN_BRACKET) return ERR_FUNC_OPEN_BRACKET; CUR++; Tree_Add_Left (tree, Node_NEW()); int ret = Get_E (tree -> left); if (ret != HAPPY) if (ret == 0) return ret; if (func == FUNC_LOG) { if ((*CUR) -> op != SEP_COMMA) return ERR_FUNC_COMMA; CUR++; ret = Tree_Add_Right (tree, Node_NEW()); if (ret != HAPPY) if (ret == 0) return ret; ret = Get_E (tree -> right); if (ret != HAPPY) if (ret == 0) return ret; } if ((*CUR) -> op != SEP_CLOSE_BRACKET) return ERR_FUNC_CLOSE_BRACKET; CUR++; tree -> type = FUNC; tree -> op = func; ASSERT_TREE_OK (tree); return HAPPY; }
static network_mysqld_python_stmt_ret proxy_python_read_auth(network_mysqld_con *con) { network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION; network_mysqld_con_python_t *st = con->plugin_con_state; if(!CHECK_FUNC(read_auth)) return ret; PyObject *result = PyObject_CallFunctionObjArgs( GET_FUNC(read_auth), st->proxy, NULL); GET_PYTHON_RESULT(read_auth) switch(ret) { case PROXY_NO_DECISION: break; case PROXY_SEND_RESULT: /* answer directly */ if (network_mysqld_con_python_handle_proxy_response(con, st->proxy)) network_mysqld_con_send_error(con->client, C("(python) handling " "proxy.response failed, check error-log")); break; case PROXY_SEND_QUERY: /* something is in the injection queue, pull it from there and replace * the content of original packet */ if (st->injected.queries->length) ret = PROXY_SEND_INJECTION; else ret = PROXY_NO_DECISION; break; default: ret = PROXY_NO_DECISION; break; } return ret; }
static network_mysqld_python_stmt_ret proxy_python_read_query_result(network_mysqld_con *con) { network_socket *send_sock = con->client; network_socket *recv_sock = con->server; injection *inj = NULL; network_mysqld_con_python_t *st = con->plugin_con_state; network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION; GString *packet; /** * check if we want to forward the statement to the client * if not, clean the send-queue */ if (0 == st->injected.queries->length) return PROXY_NO_DECISION; if(!CHECK_FUNC(read_query_result)) return ret; inj = g_queue_pop_head(st->injected.queries); inj->result_queue = con->server->recv_queue->chunks; PyObject * injection_obj = Injection_New(inj); if(!injection_obj){ PyErr_Print(); network_mysqld_con_send_error(con->client, C("PyProxy: Failed to create injection object.")); con->state = CON_STATE_SEND_ERROR; return PROXY_SEND_RESULT; } PyObject *result = PyObject_CallFunctionObjArgs( GET_FUNC(read_query_result), st->proxy, injection_obj, NULL); Py_DECREF(injection_obj); GET_PYTHON_RESULT(read_query_result) if (!con->resultset_is_needed && (PROXY_NO_DECISION != ret)) { g_critical("%s: read_query_result() in %s tries to modify the resultset, " "but hasn't asked to buffer it in proxy.query.append(..., True). " "We ignore the change to the result-set.", G_STRLOC, con->config->python_script); ret = PROXY_NO_DECISION; } switch (ret) { case PROXY_SEND_RESULT: /* we can only replace the result, if we buffer it */ g_assert_cmpint(con->resultset_is_needed, ==, TRUE); while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks))) g_string_free(packet, TRUE); if (network_mysqld_con_python_handle_proxy_response(con, st->proxy)) if (!st->injected.sent_resultset) network_mysqld_con_send_error(con->client, C("(python) handling" " proxy.response failed, check error-log")); /* fall through */ case PROXY_NO_DECISION: if (!st->injected.sent_resultset) { // make sure we send only one result-set per client-query while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks))) network_mysqld_queue_append_raw(send_sock, send_sock->send_queue, packet); st->injected.sent_resultset++; break; } g_critical("%s.%d: got asked to send a resultset, but ignoring it as " "we already have sent %d resultset(s). injection-id: %d", __FILE__, __LINE__, st->injected.sent_resultset, inj->id); st->injected.sent_resultset++; /* fall through */ case PROXY_IGNORE_RESULT: /* trash the packets for the injection query */ if (!con->resultset_is_needed) { g_critical("%s: we tried to send more than one resultset to the " "client, but didn't had them buffered. Now the client " "is out of sync may have closed the connection on us. " "Please use proxy.queries.append(..., True) to fix this.", G_STRLOC); break; } while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks))) g_string_free(packet, TRUE); break; default: /* invalid return code */ g_message("%s.%d: return-code for read_query_result() was neither " "PROXY_SEND_RESULT or PROXY_IGNORE_RESULT, will ignore the result", __FILE__, __LINE__); while ((packet = g_queue_pop_head(send_sock->send_queue->chunks))) g_string_free(packet, TRUE); break; } injection_free(inj); return ret; }