/* Do the actual work of forwarding the command from an * upstream ascii conn to its assigned ascii downstream. */ bool cproxy_forward_a2a_downstream(downstream *d) { assert(d != NULL); conn *uc = d->upstream_conn; assert(uc != NULL); assert(uc->state == conn_pause); assert(uc->cmd_start != NULL); assert(uc->thread != NULL); assert(uc->thread->base != NULL); assert(IS_ASCII(uc->protocol)); assert(IS_PROXY(uc->protocol)); if (cproxy_connect_downstream(d, uc->thread) > 0) { assert(d->downstream_conns != NULL); if (uc->cmd == -1) { return cproxy_forward_a2a_simple_downstream(d, uc->cmd_start, uc); } else { return cproxy_forward_a2a_item_downstream(d, uc->cmd, uc->item, uc); } } return false; }
/* Do the actual work of forwarding the command from an * upstream ascii conn to its assigned ascii downstream. */ bool cproxy_forward_a2a_downstream(downstream *d) { assert(d != NULL); conn *uc = d->upstream_conn; assert(uc != NULL); assert(uc->state == conn_pause); assert(uc->cmd_start != NULL); assert(uc->thread != NULL); assert(uc->thread->base != NULL); assert(IS_ASCII(uc->protocol)); assert(IS_PROXY(uc->protocol)); int server_index = -1; if (cproxy_is_broadcast_cmd(uc->cmd_curr) == true) { cproxy_ascii_broadcast_suffix(d); } else { char *key = NULL; int key_len = 0; if (ascii_scan_key(uc->cmd_start, &key, &key_len) && key != NULL && key_len > 0) { server_index = cproxy_server_index(d, key, key_len, NULL); if (server_index < 0) { return false; } } } int nc = cproxy_connect_downstream(d, uc->thread, server_index); if (nc == -1) { return true; } if (nc > 0) { assert(d->downstream_conns != NULL); if (d->usec_start == 0 && d->ptd->behavior_pool.base.time_stats) { d->usec_start = usec_now(); } if (uc->cmd == -1) { return cproxy_forward_a2a_simple_downstream(d, uc->cmd_start, uc); } else { return cproxy_forward_a2a_item_downstream(d, uc->cmd, uc->item, uc); } } if (settings.verbose > 2) { moxi_log_write("%d: cproxy_forward_a2a_downstream connect failed\n", uc->sfd); } return false; }
/* Do the actual work of forwarding the command from an * upstream binary conn to its assigned binary downstream. */ bool cproxy_forward_b2b_downstream(downstream *d) { int nc; int server_index; conn *uc; cb_assert(d != NULL); cb_assert(d->ptd != NULL); cb_assert(d->ptd->proxy != NULL); cb_assert(d->downstream_conns != NULL); cb_assert(d->downstream_used == 0); cb_assert(d->multiget == NULL); cb_assert(d->merger == NULL); d->downstream_used_start = 0; uc = d->upstream_conn; if (settings.verbose > 2) { moxi_log_write("%d: cproxy_forward_b2b_downstream %x\n", uc->sfd, uc->cmd); } cb_assert(uc != NULL); cb_assert(uc->state == conn_pause); cb_assert(uc->cmd >= 0); cb_assert(uc->cmd_start == NULL); cb_assert(uc->thread != NULL); cb_assert(uc->thread->base != NULL); cb_assert(uc->noreply == false); cb_assert(IS_BINARY(uc->protocol)); cb_assert(IS_PROXY(uc->protocol)); server_index = -1; if (cproxy_is_broadcast_cmd(uc->cmd) == false && uc->corked == NULL) { item *it = uc->item; protocol_binary_request_header *req; char *key; int key_len; cb_assert(it != NULL); req = (protocol_binary_request_header *) ITEM_data(it); key = ((char *) req) + sizeof(*req) + req->request.extlen; key_len = ntohs(req->request.keylen); if (key_len > 0) { server_index = cproxy_server_index(d, key, key_len, NULL); if (server_index < 0) { return false; } } } nc = cproxy_connect_downstream(d, uc->thread, server_index); if (nc == -1) { return true; } if (nc > 0) { int i; int nconns; cb_assert(d->downstream_conns != NULL); if (d->usec_start == 0 && d->ptd->behavior_pool.base.time_stats) { d->usec_start = usec_now(); } nconns = mcs_server_count(&d->mst); for (i = 0; i < nconns; i++) { conn *c = d->downstream_conns[i]; if (c != NULL && c != NULL_CONN) { cb_assert(c->state == conn_pause); cb_assert(c->item == NULL); if (cproxy_prep_conn_for_write(c) == false) { d->ptd->stats.stats.err_downstream_write_prep++; cproxy_close_conn(c); return false; } } } /* Uncork the saved-up quiet binary commands. */ cproxy_binary_uncork_cmds(d, uc); if (uc->cmd == PROTOCOL_BINARY_CMD_FLUSH || uc->cmd == PROTOCOL_BINARY_CMD_NOOP || uc->cmd == PROTOCOL_BINARY_CMD_STAT) { return cproxy_broadcast_b2b_downstream(d, uc); } return cproxy_forward_b2b_simple_downstream(d, uc); } if (settings.verbose > 2) { moxi_log_write("%d: cproxy_forward_b2b_downstream connect failed\n", uc->sfd); } return false; }