Beispiel #1
0
int handle_control_request(ServiceHandler h, char *buf, int bufSize)
{
    int cmd = -1;
    int dataNum = -1;

    if(bufSize == 0)
        return -1;

    int ret;
    char ppData[MAX_DATA_NUM][MAX_DATA_NUM] = {0};
    ret = parse_ctl_data(buf, bufSize, &cmd, &dataNum, ppData);
    debug_argv("cmd:%d, num:%d \n",cmd, dataNum);
    if(dataNum > 1)
    {
        ret = -1;
    }
    debug_argv("ret %d\n",ret);
    if(-1 == ret)
    {
        debug_argv("\n");
        error_response(h,"Data Format Error!\n");
        return -1;
    }
    if(cmd == CTL_REG_CMD && (dataNum == 1 || dataNum == 0))
    {
        debug_argv("handleControlrequests!!\n");
        if(dataNum == 1)
        {
            add_cluster_nodes(cluster_nodes_g, ppData,dataNum);
        }
        int nodeNum = MAX_DATA_NUM;
        cluster_nodes_info(cluster_nodes_g,ppData,&nodeNum);

        for(ret = 0;ret<nodeNum;ret++)
            debug_argv("%s\n",ppData[ret]);

        bufSize = MAX_BUF_LEN;
        format_ctl_data(buf,&bufSize,CTL_REG_CMD,ppData,nodeNum);
        send_data(h,buf,bufSize);

    }
    else
    {
        debug_argv("\n");
        error_response(h,"Unknow Request!\n");
        return -1;
    }
    return 0;
}
Beispiel #2
0
void 
cachedb_operate(struct module_qstate* qstate, enum module_ev event, int id,
	struct outbound_entry* outbound)
{
	struct cachedb_env* ie = (struct cachedb_env*)qstate->env->modinfo[id];
	struct cachedb_qstate* iq = (struct cachedb_qstate*)qstate->minfo[id];
	verbose(VERB_QUERY, "cachedb[module %d] operate: extstate:%s event:%s", 
		id, strextstate(qstate->ext_state[id]), strmodulevent(event));
	if(iq) log_query_info(VERB_QUERY, "cachedb operate: query", 
		&qstate->qinfo);

	/* perform cachedb state machine */
	if((event == module_event_new || event == module_event_pass) && 
		iq == NULL) {
		if(!cachedb_new(qstate, id)) {
			(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
			return;
		}
		iq = (struct cachedb_qstate*)qstate->minfo[id];
	}
	if(iq && (event == module_event_pass || event == module_event_new)) {
		cachedb_handle_query(qstate, iq, ie, id);
		return;
	}
	if(iq && (event == module_event_moddone)) {
		cachedb_handle_response(qstate, iq, ie, id);
		return;
	}
	if(iq && outbound) {
		/* cachedb does not need to process responses at this time
		 * ignore it.
		cachedb_process_response(qstate, iq, ie, id, outbound, event);
		*/
		return;
	}
	if(event == module_event_error) {
		verbose(VERB_ALGO, "got called with event error, giving up");
		(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
		return;
	}
	if(!iq && (event == module_event_moddone)) {
		/* during priming, module done but we never started */
		qstate->ext_state[id] = module_finished;
		return;
	}

	log_err("bad event for cachedb");
	(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
Beispiel #3
0
int connection_proxy_req_parse(Connection *conn)
{
    int rc = 0;
    Host *target_host = conn->req->target_host;
    Backend *req_action = conn->req->action;

    check_debug(!IOBuf_closed(conn->iob), "Client closed, goodbye.");

    rc = Connection_read_header(conn, conn->req);

    check_debug(rc > 0, "Failed to read another header.");
    error_unless(Request_is_http(conn->req), conn, 400,
            "Someone tried to change the protocol on us from HTTP.");

    Backend *found = Host_match_backend(target_host, Request_path(conn->req), NULL);
    error_unless(found, conn, 404, 
            "Handler not found: %s", bdata(Request_path(conn->req)));

    // break out of PROXY if the actions don't match
    if(found != req_action) {
        Request_set_action(conn->req, found);
        return Connection_backend_event(found, conn);
    } else {
        return HTTP_REQ;
    }

    error_response(conn, 500, "Invalid code branch, tell Zed.");
error:
    return REMOTE_CLOSE;
}
Beispiel #4
0
// complete the response to a get request.
void finish_get_command(conn *c) {
	item *it;
	int i;

	// setup all items for writing out.
	for (i = 0; i < c->ileft; i++) {
		it = *(c->ilist + i);
		if (it) {
			// Construct the response. Each hit adds three elements to the
			// outgoing data list:
			//   "VALUE <key> <flags> <data_length>\r\n"
			//   "<data>\r\n"
			// The <data> element is stored on the connection item list, not on
			// the iov list.
			if (!conn_add_iov(c, "VALUE ", 6) ||
				 !conn_add_iov(c, ITEM_key(it), it->nkey) ||
				 !conn_add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes)) {
				item_remove(it);
				error_response(c, "SERVER_ERROR out of memory writing get response");
				return;
			}

			if (config.verbose > 1) {
				fprintf(stderr, ">%d sending key %s\n", c->sfd, ITEM_key(it));
			}
		} else {
			fprintf(stderr, "ERROR corrupted ilist!\n");
			exit(1);
		}
	}

	if (config.verbose > 1) {
		fprintf(stderr, ">%d END\n", c->sfd);
	}

	if (!conn_add_iov(c, "END\r\n", 5) != 0) {
		error_response(c, "SERVER_ERROR out of memory writing get response");
	} else {
		conn_set_state(c, conn_mwrite);
	}
}
Beispiel #5
0
static void ironbee_plugin_send_response_hdr(TSCont contp, TSHttpTxn txnp)
{
    assert(contp != NULL);
    assert(txnp != NULL);

    tsib_txn_ctx *txndata;

    txndata = TSContDataGet(contp);
    if (txndata == NULL) {
        /* Ironbee is unavailable to help with our response. */
        /* This contp is not ours, so we leave it. */
        internal_error_response(txnp);
        TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
        return;
    }

    /* If ironbee has sent us into an error response then
     * we came here in our error path, with nonzero status.
     */
    if (txndata->status != 0) {
        error_response(txnp, txndata);
    }

    /* Feed ironbee the headers if not done already. */
    if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_STARTED)) {
        if (process_hdr(txndata, txnp, &tsib_direction_client_resp) != HDR_OK) {
            /* I think this is a shouldn't happen event, and that
             * if it does we have an ironbee bug or misconfiguration.
             * Log an error to catch if it happens in practice.
             */
            ib_log_error_tx(txndata->tx, "process_hdr returned error in send_response_hdr event");
        }
    }

    /* If there is an ironbee-generated response body, notify ironbee.
     *
     * NOTE: I do not see anywhere else to put this as the error body is
     *       just a buffer and not delivered via normal IO channels, so
     *       the error body will never get caught by an event.
     */
    if ((txndata->status != 0) && (txndata->err_body != NULL)) {
        const char *data = txndata->err_body;
        size_t data_length = txndata->err_body_len;
        ib_log_debug_tx(txndata->tx,
                "error_response: calling ib_state_notify_response_body_data() %s:%d",
                __FILE__, __LINE__);
        ib_state_notify_response_body_data(txndata->tx->ib,
                                           txndata->tx,
                                           data, data_length);
    }

    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
Beispiel #6
0
// process a memcached set command.
void process_update_command(conn *c, token_t *tokens,
                            const size_t ntokens,
                            int comm, bool handle_cas) {
	int vlen;
	assert(c != NULL);

	if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH ||
	    !safe_strtol(tokens[4].value, (int32_t *)&vlen)) {
		error_response(c, "CLIENT_ERROR bad command line format");
		return;
	}

	if (vlen < 0) {
		error_response(c, "CLIENT_ERROR bad command line format");
		return;
	}

	// setup value to be read
	c->sbytes = vlen + 2; // for \r\n consumption.
	conn_set_state(c, conn_read_value);
}
bool proc (geonlp::ServicePtr service, const std::string& request_json, picojson::value& response) {
  picojson::ext req;

  if (request_json.length() == 0) return false;
  try {
    req.initByJson(request_json);
  } catch (picojson::PicojsonException e) {
    error_response(std::string("Request string is not a valid JSON representation."));
    exit(0);
  }
  response = service->proc(picojson::value(req));
  return true;
}
// Get POST message from stdin to string
void get_post_message(std::string& message) {
  message = "";
  char* cp = getenv("CONTENT_LENGTH");
  if (!cp) {
    error_response(std::string("CONTENT_LENGTH is not defined."));
    exit(0);
  }
  int len = atoi(getenv("CONTENT_LENGTH"));
  char buf[len + 1];
  std::cin.read(buf, len);
  buf[len] = '\0';
  message = buf;
}
Beispiel #9
0
static inline int Connection_backend_event(Backend *found, Connection *conn)
{
    switch(found->type) {
        case BACKEND_HANDLER:
            return HANDLER;
        case BACKEND_DIR:
            return DIRECTORY;
        case BACKEND_PROXY:
            return PROXY;
        default:
            error_response(conn, 501, "Invalid backend type: %d", found->type);
    }

error:
    return CLOSE;
}
Beispiel #10
0
int connection_identify_request(Connection *conn)
{
    int next = CLOSE;

    if(Request_is_xml(conn->req)) {
        if(biseq(Request_path(conn->req), &POLICY_XML_REQUEST)) {
            debug("XML POLICY CONNECTION: %s", bdata(Request_path(conn->req)));
            conn->type = CONN_TYPE_SOCKET;
            taskname("XML");
            next = SOCKET_REQ;
        } else {
            debug("XML MESSAGE");
            conn->type = CONN_TYPE_MSG;
            taskname("MSG");
            next = MSG_REQ;
        }
    } else if(Request_is_json(conn->req)) {
        debug("JSON SOCKET MESSAGE");
        conn->type = CONN_TYPE_MSG;
        taskname("MSG");
        next = MSG_REQ;
    } else if(Request_is_websocket(conn->req)) {
        debug("WEBSOCKET MESSAGE");
        conn->type = CONN_TYPE_SOCKET;
        taskname("WS");
        next = WS_REQ;
    } else if(Request_is_http(conn->req)) {
        debug("HTTP MESSAGE");
        conn->type = CONN_TYPE_HTTP;
        taskname("HTTP");
        next = HTTP_REQ;
    } else {
        error_response(conn, 500, "Invalid code branch, tell Zed.");
    }

    return next;

error:
    return CLOSE;

}
Beispiel #11
0
static inline int ident_and_register(Connection *conn, int reg_too)
{
    int next = CLOSE;

    if(Request_is_xml(conn->req)) {
        if(biseq(Request_path(conn->req), &POLICY_XML_REQUEST)) {
            debug("XML POLICY CONNECTION");
            conn->type = CONN_TYPE_SOCKET;
            taskname("XML");
            next = SOCKET_REQ;
        } else {
            debug("XML MESSAGE");
            conn->type = CONN_TYPE_MSG;
            taskname("MSG");
            next = MSG_REQ;
        }
    } else if(Request_is_json(conn->req)) {
        debug("JSON SOCKET MESSAGE");
        conn->type = CONN_TYPE_MSG;
        taskname("MSG");
        next = MSG_REQ;
    } else if(Request_is_http(conn->req)) {
        debug("HTTP MESSAGE");
        conn->type = CONN_TYPE_HTTP;
        taskname("HTTP");
        next = HTTP_REQ;
    } else {
        error_response(conn, 500, "Invalid code branch, tell Zed.");
    }

    if(reg_too) Register_connect(IOBuf_fd(conn->iob), (void*)conn);
    return next;

error:
    return CLOSE;

}
Beispiel #12
0
int main(int argc, char* argv[])
{
  default_id = picojson::value(long(0));
  
  char* cp = getenv("REQUEST_METHOD");
  if (!cp) {
    error_response(std::string("Unknown method '") + cp + "'.");
    exit(0);
  }
  if (!strcmp(cp, "POST")) {
    std::string request;
    get_post_message(request);
    
    try {
      geonlp::ServicePtr service = geonlp::createService();
      picojson::value response;
      proc(service, request, response);
      std::cout << "Content-Type: application/json; charset=utf-8\n";
      std::cout << "Access-Control-Allow-Origin: *\n\n";
      std::cout << response.serialize();
    } catch (geonlp::ServiceCreateFailedException& e) {
      json_error_response(e.what(), default_id);
      exit(0);
    }
  } else if (strcmp(cp, "GET") && strcmp(cp, "HEAD")) {
    // Preflignted requests
    std::cout << "Access-Control-Allow-Origin: *\n";
    std::cout << "Access-Control-Allow-Methods: POST, OPTIONS\n";
    std::cout << "Access-Control-Allow-Headers: X-GeoNLP-Authorization, Content-type\n";
    std::cout << "Access-Control-Max-Age: 3600\n";
    std::cout << "Content-Length: 0\n";
    std::cout << "Content-Type: text/plain\n\n";
    exit(0);
  }

  return 0;
}
static int mdrc_gains(double *bands, int nb_bands, t_mdrc_gains **p_p_mdrc_gains)
// inputs :
//      bands           : band cut off frequencies (first band cut off frequency = 0)
//      nb_bands        : number of bands (1 to 5)
//
// outputs (into **p_p_mdrc_gains) :
//      index           : index of filter for each band
//      gains           : best found gains for each band
//      band_responses  : response of each band
//      global_response : global response
//      error           : error
{
    double FreqCutoff[]   = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 110, 120, 130, 140, 150, 160, 170};

    //                             b2,    -b1/2,      b0,   -a1/2,      a2
    double LPCoefTab[][5] = {{      0,       -0,       0, 8388607, 8388607},
                             {    356,     -356,     356, 8310966, 8234749},
                             {   1411,    -1411,    1411, 8233344, 8083724},
                             {   3146,    -3146,    3146, 8155760, 7935495},
                             {   5541,    -5541,    5541, 8078234, 7790021},
                             {   8577,    -8577,    8577, 8000780, 7647261},
                             {  12238,   -12238,   12238, 7923418, 7507178},
                             {  16504,   -16504,   16504, 7846162, 7369732},
                             {  21358,   -21358,   21358, 7769030, 7234882},
                             {  26783,   -26783,   26783, 7692034, 7102590},
                             {  32761,   -32761,   32761, 7615190, 6972818},
                             {  70399,   -70399,   70399, 7233707, 6360402},
                             { 119556,  -119556,  119556, 6857840, 5805295},
                             { 178504,  -178504,  178504, 6488789, 5302984},
                             { 245707,  -245707,  245707, 6127486, 4849190},
                             { 319807,  -319807,  319807, 5774638, 4439894},
                             { 399607,  -399607,  399607, 5430758, 4071336},
                             { 484057,  -484057,  484057, 5096202, 3740025},
                             { 572239,  -572239,  572239, 4771190, 3442727},
                             { 663351,  -663351,  663351, 4455832, 3176458},
                             { 756697,  -756697,  756697, 4150147, 2938474},
                             { 851674,  -851674,  851674, 3854084, 2726259},
                             { 947762,  -947762,  947762, 3567532, 2537505},
                             {1044512, -1044512, 1044512, 3290333, 2370105},
                             {1141538, -1141538, 1141538, 3022295, 2222134},
                             {1238513, -1238513, 1238513, 2763196, 2091835},
                             {1335156, -1335156, 1335156, 2512796, 1977608},
                             {1431229, -1431229, 1431229, 2270842, 1877993},
                             {1526534, -1526534, 1526534, 2037068, 1791664},
                             {1714194, -1714194, 1714194, 1592982, 1654134},
                             {1897115, -1897115, 1897115, 1178372, 1556594},
                             {2074617, -2074617, 2074617,  791105, 1492071},
                             {2246282, -2246282, 2246282,  429132, 1454786},
                             {2411881, -2411881, 2411881,   90515, 1439948},
                             {2571327, -2571327, 2571327, -226558, 1443585},
                             {2724636, -2724636, 2724636, -523771, 1462394}};

    double HPCoefTab[][5] = {{8388607,  8388607, 8388607, 8388607, 8388607},
                             {8311322,  8311322, 8311322, 8310966, 8234749},
                             {8234756,  8234756, 8234756, 8233344, 8083724},
                             {8158906,  8158906, 8158906, 8155760, 7935495},
                             {8083774,  8083774, 8083774, 8078234, 7790021},
                             {8009357,  8009357, 8009357, 8000780, 7647261},
                             {7935656,  7935656, 7935656, 7923418, 7507178},
                             {7862666,  7862666, 7862666, 7846162, 7369732},
                             {7790387,  7790387, 7790387, 7769030, 7234882},
                             {7718816,  7718816, 7718816, 7692034, 7102590},
                             {7647952,  7647952, 7647952, 7615190, 6972818},
                             {7304106,  7304106, 7304106, 7233707, 6360402},
                             {6977396,  6977396, 6977396, 6857840, 5805295},
                             {6667292,  6667292, 6667292, 6488789, 5302984},
                             {6373192,  6373192, 6373192, 6127486, 4849190},
                             {6094444,  6094444, 6094444, 5774638, 4439894},
                             {5830366,  5830366, 5830366, 5430758, 4071336},
                             {5580260,  5580260, 5580260, 5096202, 3740025},
                             {5343428,  5343428, 5343428, 4771190, 3442727},
                             {5119182,  5119182, 5119182, 4455832, 3176458},
                             {4906844,  4906844, 4906844, 4150147, 2938474},
                             {4705759,  4705759, 4705759, 3854084, 2726259},
                             {4515294,  4515294, 4515294, 3567532, 2537505},
                             {4334844,  4334844, 4334844, 3290333, 2370105},
                             {4163833,  4163833, 4163833, 3022295, 2222134},
                             {4001709,  4001709, 4001709, 2763196, 2091835},
                             {3847952,  3847952, 3847952, 2512796, 1977608},
                             {3702071,  3702071, 3702071, 2270842, 1877993},
                             {3563602,  3563602, 3563602, 2037068, 1791664},
                             {3307176,  3307176, 3307176, 1592982, 1654134},
                             {3075486,  3075486, 3075486, 1178372, 1556594},
                             {2865722,  2865722, 2865722,  791105, 1492071},
                             {2675414,  2675414, 2675414,  429132, 1454786},
                             {2502396,  2502396, 2502396,   90515, 1439948},
                             {2344769,  2344769, 2344769, -226558, 1443585},
                             {2200865,  2200865, 2200865, -523771, 1462394}};

    const int    nb_filters = sizeof(FreqCutoff) / sizeof(*FreqCutoff);
    double       coef = pow(2.0, -23.0);
    double       swap_tmp, max_response;
    double       error, best_error, error_max, dx;
    double       weigthing[N];
    double       best_gains[NB_BANDS_MAX];
    int          i, j, counter, counter_max;
    t_mdrc_gains *p_mdrc_gains;
    int          *p_index;
    double       *p_gains;
    t_complex    *p_band_response;
    t_complex    *p_global_response;


    nb_bands = (nb_bands > NB_BANDS_MAX ? NB_BANDS_MAX : nb_bands);

    p_mdrc_gains = (t_mdrc_gains *) malloc(sizeof(t_mdrc_gains));
    if(p_mdrc_gains == NULL)
    {
        return -1;
    }
    p_index           = p_mdrc_gains->index;
    p_gains           = p_mdrc_gains->gains;
    p_global_response = p_mdrc_gains->global_response;
    *p_p_mdrc_gains   = p_mdrc_gains;

    for(i = 0; i < sizeof(FreqCutoff) / sizeof(*FreqCutoff); i++)
    {
        FreqCutoff[i] *= 100.0;
    }
    for(i = 0; i < sizeof(LPCoefTab) / sizeof(*LPCoefTab); i++)
    {
        swap_tmp         = LPCoefTab[i][2] * coef;
        LPCoefTab[i][2]  = LPCoefTab[i][0] * coef;
        LPCoefTab[i][0]  = swap_tmp;
        LPCoefTab[i][1] *= coef * -2.0;
        LPCoefTab[i][3] *= coef * -2.0;
        LPCoefTab[i][4] *= coef;
    }
    for(i = 0; i < sizeof(HPCoefTab) / sizeof(*HPCoefTab); i++)
    {
        swap_tmp         = HPCoefTab[i][2] * coef;
        HPCoefTab[i][2]  = HPCoefTab[i][0] * coef;
        HPCoefTab[i][0]  = swap_tmp;
        HPCoefTab[i][1] *= coef * -2.0;
        HPCoefTab[i][3] *= coef * -2.0;
        HPCoefTab[i][4] *= coef;
    }
    compute_weigthing(weigthing);

    if(nb_bands > 1)
    {
        for(i = 1; i < nb_bands; i++)
        {
            for(j = 0; j < nb_filters; j++)
            {
                if(bands[i] <= FreqCutoff[j])
                {
                    p_index[i - 1] = j;

                    // select nearest frequency
                    if(j > 0)
                    {
                        if((FreqCutoff[j] - bands[i]) > (bands[i] - FreqCutoff[j - 1]))
                        {
                            p_index[i - 1] = j - 1;
                        }
                    }
                    break;
                }
            }
        }


        for(i = 0; i < nb_bands; i++)
        {
            double max_square;
            int    index_LP, index_HP;

            p_band_response = p_mdrc_gains->band_responses[i];
            if(i == 0)
            {
                index_LP = p_index[i];
                response(LPCoefTab[index_LP][0], LPCoefTab[index_LP][1], LPCoefTab[index_LP][2], LPCoefTab[index_LP][3], LPCoefTab[index_LP][4],
                         1.0,                    0.0,                    0.0,                    0.0,                    0.0,
                         p_band_response);
            }
            else if(i < nb_bands - 1)
            {
                index_LP = p_index[i];
                index_HP = p_index[i - 1];
                response(LPCoefTab[index_LP][0], LPCoefTab[index_LP][1], LPCoefTab[index_LP][2], LPCoefTab[index_LP][3], LPCoefTab[index_LP][4],
                         HPCoefTab[index_HP][0], HPCoefTab[index_HP][1], HPCoefTab[index_HP][2], HPCoefTab[index_HP][3], HPCoefTab[index_HP][4],
                         p_band_response);
            }
            else
            {
                index_HP = p_index[i - 1];
                response(1.0,                    0.0,                    0.0,                    0.0,                    0.0,
                         HPCoefTab[index_HP][0], HPCoefTab[index_HP][1], HPCoefTab[index_HP][2], HPCoefTab[index_HP][3], HPCoefTab[index_HP][4],
                         p_band_response);
            }

            max_square = 0.0;
            for(j = 0; j < N; j++)
            {
                double square = p_band_response[j].re * p_band_response[j].re + p_band_response[j].im * p_band_response[j].im;

                if(square > max_square)
                {
                    max_square = square;
                }
            }
            p_gains[i] = 1.0 / sqrt(max_square);
        }

        error = error_response(p_mdrc_gains, p_gains, nb_bands, weigthing);
        memcpy(best_gains, p_gains, nb_bands * sizeof(double));
        best_error  = error;
        dx          = 0.1;
        error_max   = 0.05;
        counter     = 1;
        counter_max = 1000000;
        display_result(counter, error, dx);

        // coarse gains search
        while((best_error > error_max) && (counter < counter_max))
        {
            solve_gains(&counter, dx, 5, nb_bands, best_gains, &best_error, p_mdrc_gains, weigthing, error_max, counter_max);
            dx *= 0.5;
        }

        // fine gains search
        counter_max *= 2;
        error_max   *= 0.2;
        dx          *= 0.2;
        solve_gains(&counter, dx, 10, nb_bands, best_gains, &best_error, p_mdrc_gains, weigthing, error_max, counter_max);

        memcpy(p_gains, best_gains, nb_bands * sizeof(double));
        error = best_error;
        display_result(counter, error, dx);
    }
    else
    {
        p_index[0] = 0;
        p_gains[0] = 1.0;
        response(1.0, 0.0, 0.0, 0.0, 0.0,
                 1.0, 0.0, 0.0, 0.0, 0.0,
                 p_mdrc_gains->band_responses[0]);
        error = error_response(p_mdrc_gains, p_gains, nb_bands, weigthing);
        printf("no sub-band\n");
    }

    for(i = 0; i < N; i++)
    {
        p_global_response[i].re = 0.0;
        p_global_response[i].im = 0.0;
        for(j = 0; j < nb_bands; j++)
        {
            p_global_response[i].re += p_gains[j] * p_mdrc_gains->band_responses[j][i].re;
            p_global_response[i].im += p_gains[j] * p_mdrc_gains->band_responses[j][i].im;
        }
    }

    p_mdrc_gains->error = error;

    return 0;
}
Beispiel #14
0
int handle_one_request(ServiceHandler h, char *buf, int buf_size)
{

    debug;
    char Buf[MAX_BUF_LEN] = "\0";
    int BufSize = MAX_BUF_LEN;
    char Data1[MAX_BUF_LEN] = "\0";
    char Data2[MAX_BUF_LEN] = "\0";

    mDataFormat data = (mDataFormat) malloc(sizeof(struct DataFormat));
    data->value1 = Data1;
    data->value2 = Data2;

    memset(Data1, 0, MAX_BUF_LEN);
    memset(Data2, 0, MAX_BUF_LEN);
    data->value1 = Data1;
    data->value2 = Data2;

    /*if(receive_data(h,Buf,&BufSize) == 0)
      {
          fprintf(stderr,"Connection Error,%s:%d\n",__FILE__,__LINE__);
          return -1;            
      }*/
    if(BufSize == 0)
    {
        free(data);
        return -1;
    }
    int ret = parse_data(buf,data);

    // print the received data
    // printRec(data);

    if(ret == -1)
    {
        error_response(h,"Data Format Error!\n");
        printf("server parse_data error!\n");
        free(data);
        return -1;
    }
    if(data->cmd == OPEN_CMD)
    {
        debug;
        Database db = createNewDB(data->value1);
        debug_argv("open db:%p\n",db);
        match_sockfd_mdb(h, db);
        BufSize = MAX_BUF_LEN;
        data->value_num = 0;
        BufSize = format_data(Buf,data);
        assert(BufSize > 0);
        send_data(h,Buf,BufSize);
    }
    else if(data->cmd == CLOSE_CMD)
    {
        debug_argv("close db\n");
        Database db = NULL;
        get_mdb(h, &db);
        closeDB(db);
        BufSize = MAX_BUF_LEN;
        data->value_num = 0;
        BufSize = format_data(Buf,data);
        send_data(h,Buf,BufSize);
        detach_sockfd_mdb(h);
        service_stop(h);
        free(data);
        return 0;
    }
    else if(data->cmd == GET_CMD)
    {
        Database db = NULL;
        get_mdb(h, &db);

        //debug_argv("get db:%p\n",db);
        int key = *(int *)data->value1;
        Data value;

        char tem[MAX_BUF_LEN] = "\0";
        value.value = tem;
        ret = getValueByKey(db, key, &value);
       // printf("server getdata value => %s\n", value.value);
        if(ret == -1)
        {
            error_response(h,"The key NOT FOUND!\n");
            free(data);
            return -1;              
        }
        BufSize = MAX_BUF_LEN;
        data->value_num = 1;
        data->len_value1 = strlen(value.value);
        data->value1 = value.value;
        BufSize = format_data(Buf,data);
        send_data(h,Buf,BufSize);

    }
    else if(data->cmd == SET_CMD)
    {
        int key = *(int *)data->value1;
        Data value;
        value.value = data->value2;
        value.length = data->len_value2;
        Database db = NULL;
        get_mdb(h, &db);
        debug_argv("set: db:%p\n",db);
        ret = putKeyValue(db,key,&value);
        if (ret == -1)
        {
            error_response(h,"Save key & value error!\n");
            printf("set error : %d, %s\n", key, value.value);
            free(data);
            return -1;
        }
        BufSize = MAX_BUF_LEN;
        data->value_num = 0;
        BufSize = format_data(Buf,data);
        send_data(h,Buf,BufSize);    

    }
    else if(data->cmd == DEL_CMD)
    {
        int key = *(int *)data->value1;;           
        Database db = NULL;
        get_mdb(h, &db);
        debug_argv("delete: db:%p\n",db);
        ret = deleteValueByKey(db,key);
        if(ret == -1)
        {
            error_response(h,"The key NOT FOUND!\n");
            free(data);
            return -1;
        }            
        BufSize = MAX_BUF_LEN;
        data->value_num = 0;
        BufSize = format_data(Buf,data);
        send_data(h,Buf,BufSize);             
    }
    else
    {
        printf("Unknow Request!\n");
        error_response(h, "Unknow Request!\n");
    }                                   
    free(data);
    return 0;
}
    void UdpServerListenHandler::HandleReadBlock(const ErrorCode & error_code, const boost::shared_ptr<BlockData> & block,
        const RID & resource_id, boost::uint32_t transaction_id, boost::uint16_t block_index,
        const std::set<boost::uint16_t> & subpiece_indexs, boost::uint16_t dest_protocol_version,
        const boost::asio::ip::udp::endpoint & end_point)
    {
        if (!server_)
        {
            return;
        }

        if (error_code == ErrorCodes::Success)
        {
            for(std::set<boost::uint16_t>::const_iterator iter = subpiece_indexs.begin(); iter != subpiece_indexs.end(); ++iter)
            {
                protocol::SubPieceInfo sub_piece_info = RequestParser::ParseFromSNToPeer(block_index, *iter);
                boost::uint16_t subpiece_index = *iter;

                if (subpiece_index < block->GetSubPieceNumber())
                {
                    statistics_->OnSubPieceResponseSent();

                    boost::shared_ptr<ResponseTask> subpiece_response(
                        new SubPieceResponseTask(
                            end_point, 
                            block,
                            subpiece_index,
                            transaction_id,
                            resource_id,
                            guid_,
                            sub_piece_info,
                            dest_protocol_version));

                    AddResponseTask(subpiece_response);
                }
                else
                {
                    statistics_->OnError(ErrorCodes::ResourceNotFound);

                    boost::shared_ptr<ResponseTask> error_response(
                        new ErrorResponseTask(
                            end_point, 
                            transaction_id, 
                            resource_id, 
                            guid_, 
                            protocol::ErrorPacket::PPV_SUBPIECE_NO_RESOURCEID, 
                            dest_protocol_version));

                    AddResponseTask(error_response);
                }
            }
        }
        else
        {
            statistics_->OnError(error_code);

            boost::shared_ptr<ResponseTask> error_response(
                new ErrorResponseTask(
                end_point, 
                transaction_id, 
                resource_id, 
                guid_, 
                protocol::ErrorPacket::PPV_SUBPIECE_NO_RESOURCEID, 
                dest_protocol_version));

            AddResponseTask(error_response);
        }
    }
Beispiel #16
0
// process a memcached get(s) command. (we don't support CAS).
void process_get_command(conn *c, token_t *tokens, size_t ntokens,
                                bool return_cas) {
	char *key;
	size_t nkey;
	int i = 0;
	item *it;
	token_t *key_token = &tokens[KEY_TOKEN];
	char *suffix;

	assert(c != NULL);

	if (config.alloc && c->mem_blob == NULL) {
		long size = config.alloc_mean + gsl_ran_gaussian(c->thread->r, config.alloc_stddev);
		size = size <= 0 ? 10 : size;
		if (config.verbose > 0) {
			fprintf(stderr, "allocated blob: %ld\n", size);
		}

		c->mem_blob = malloc(sizeof(char) * size);
		c->mem_free_delay = 0;

		if (config.rtt_delay) {
			double r = config.rtt_mean + gsl_ran_gaussian(c->thread->r, config.rtt_stddev);
			if (r >= config.rtt_cutoff) {
				int wait = r / 100;
				if (config.verbose > 0) {
					fprintf(stderr, "delay: %d\n", wait);
				}
				c->mem_free_delay = wait;
				conn_set_state(c, conn_mwrite);
			}
		}
	}

	// process the whole command line, (only part of it may be tokenized right now)
	do {
		// process all tokenized keys at this stage.
		while(key_token->length != 0) {
			key = key_token->value;
			nkey = key_token->length;

			if(nkey > KEY_MAX_LENGTH) {
				error_response(c, "CLIENT_ERROR bad command line format");
				return;
			}

			// lookup key-value.
			it = item_get(key, nkey);
			
			// hit.
			if (it) {
				if (i >= c->isize && !conn_expand_items(c)) {
					item_remove(it);
					break;
				}

				// Construct the response. Each hit adds three elements to the
				// outgoing data list:
				//   "VALUE <key> <flags> <data_length>\r\n"
				//   "<data>\r\n"
				// The <data> element is stored on the connection item list, not on
				// the iov list.
				if (!conn_add_iov(c, "VALUE ", 6) != 0 ||
				    !conn_add_iov(c, ITEM_key(it), it->nkey) != 0 ||
				    !conn_add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) {
					item_remove(it);
					break;
				}

				if (config.verbose > 1) {
					fprintf(stderr, ">%d sending key %s\n", c->sfd, key);
				}

				// add item to remembered list (i.e., we've taken ownership of them
				// through refcounting and later must release them once we've
				// written out the iov associated with them).
				item_update(it);
				*(c->ilist + i) = it;
				i++;
			}

			key_token++;
		}

		/*
		 * If the command string hasn't been fully processed, get the next set
		 * of tokens.
		 */
		if(key_token->value != NULL) {
			ntokens = tokenize_command(key_token->value, tokens, MAX_TOKENS);
			key_token = tokens;
		}

	} while(key_token->value != NULL);

	c->icurr = c->ilist;
	c->ileft = i;

	if (config.verbose > 1) {
		fprintf(stderr, ">%d END\n", c->sfd);
	}

	// If the loop was terminated because of out-of-memory, it is not reliable
	// to add END\r\n to the buffer, because it might not end in \r\n. So we
	// send SERVER_ERROR instead.
	if (key_token->value != NULL || !conn_add_iov(c, "END\r\n", 5) != 0) {
		error_response(c, "SERVER_ERROR out of memory writing get response");
	} else {
		conn_set_state(c, conn_mwrite);
	}
}
    void UdpServerListenHandler::OnUdpRecv(protocol::Packet const & packet)
    {
        if (!server_)
        {
            return;
        }

        if (packet.PacketAction == protocol::RequestSubPiecePacketFromSN::Action)
        {
            statistics_->OnRequestForSubPieceReceived();
            SessionManager::Type error_type = session_manager_->TryAddSession(packet.end_point, packet.transaction_id_);
            if (error_type == SessionManager::NewSessionCreated || error_type == SessionManager::SessionAlreadyExists)
            {
                if (error_type == SessionManager::NewSessionCreated)
                {
                    statistics_->OnNewSessionAccepted();
                }

                std::map<boost::uint16_t, std::set<boost::uint16_t> > request_in_sn_type;

                protocol::RequestSubPiecePacketFromSN const & request_subpiece_packet =
                    static_cast<protocol::RequestSubPiecePacketFromSN const &>(packet);

                RequestParser::ParseFromPeerToSN(request_subpiece_packet, request_in_sn_type);

                size_t sub_piece_cnt = 0;

                for (std::map<boost::uint16_t, std::set<boost::uint16_t> >::const_iterator iter = request_in_sn_type.begin();
                    iter != request_in_sn_type.end(); ++iter)
                {
                    memory_cache_->AsyncReadBlock(request_subpiece_packet.resource_name_, iter->first, *(iter->second.begin()),
                        boost::bind(&UdpServerListenHandler::HandleReadBlock, shared_from_this(), _1, _2,
                        request_subpiece_packet.resource_id_, request_subpiece_packet.transaction_id_,
                        iter->first, iter->second,
                        request_subpiece_packet.protocol_version_, request_subpiece_packet.end_point));

                    statistics_->OnBlockSubpieceDensityStat(*(iter->second.begin()), *(iter->second.rbegin()), iter->second.size());

                    sub_piece_cnt += iter->second.size();
                }

                if (sub_piece_cnt)
                    statistics_->OnResourceSubpieceDensityStat(
                            request_in_sn_type.begin()->first * (BlockData::MaxBlockSize / SUB_PIECE_SIZE) + *request_in_sn_type.begin()->second.begin(),
                            request_in_sn_type.rbegin()->first * (BlockData::MaxBlockSize / SUB_PIECE_SIZE) + *request_in_sn_type.rbegin()->second.rbegin(),
                            sub_piece_cnt
                        );
            }
            else if (error_type == SessionManager::MaxSessionNumberReached)
            {
                const protocol::RequestSubPiecePacketFromSN & sn_packet = dynamic_cast<const protocol::RequestSubPiecePacketFromSN&>(packet);

                boost::shared_ptr<ResponseTask> error_response(
                    new ErrorResponseTask(
                        sn_packet.end_point, 
                        sn_packet.transaction_id_, 
                        sn_packet.resource_id_, 
                        guid_, 
                        protocol::ErrorPacket::PPV_CONNECT_CONNECTION_FULL, 
                        sn_packet.protocol_version_));
                
                AddResponseTask(error_response);

                statistics_->OnNewSessionRejected();
            } 
            else 
            {
                statistics_->OnDuplicateRequestReceived();
            }
        }
        else if (packet.PacketAction == protocol::CloseSessionPacket::Action)
        {
            session_manager_->CloseSession(packet.end_point);
            statistics_->OnClientClosedSession();
        }
        else
        {
            statistics_->OnUnknownPacketReceived();
            LOG4CPLUS_WARN(Loggers::UdpServer(), "UdpServer received illegal packet.");
        }

        if (time_counter_.elapse() >= UdpServerStatistics::StatisticsIntervalInSeconds*1000)
        {
            statistics_->ReportStatus(session_manager_);
            time_counter_.reset();
        }
    }
Beispiel #18
0
/*
 * POSIX 環境マネージャのメインルーチン
 *
 * 次の処理を行う
 *
 * ・初期化
 *   ポートマネージャに要求受け付け用のポートを登録する
 *   ファイルシステム/プロセス/メモリの各処理の初期化を行う
 *
 * ・要求の受け付け
 *   要求の受け付けは、要求受け付けポートによって行う。
 *
 * ・要求の処理
 *
 *   要求の受けつけから処理がおわるまでは他の要求は受け付けない。
 */
void
posix_start (void)
{
  struct posix_request	request;
#if 0
  extern B		_end;
#endif

  if (init_port () == FAIL)
    {
      dbg_printf ("Cannot allocate port.\n");
      slp_tsk ();
    }
  init_log ();
#if 0
  /* これではプログラムの最後をとることはできない */
  init_malloc ((UW)&_end);
#else
  /* 余裕を見て設定してあるが、manager が大きくなったときには調整が必要 */
  init_malloc (0x100000);
#endif

  /* 各機能単位での初期化
   */
  init_fs ();
  init_process ();
  init_memory ();

  banner ();

  for (;;)
    {
      /* 次の要求メッセージを待つ */
      if (get_request (&request) == FAIL)
	{
	  /* リクエスト取得に失敗した */
#ifdef DEBUG
	  dbg_printf ("Cannot get request.\n");
#endif
	  continue;
	}

#ifdef DEBUG
      dbg_printf ("OP = %d\n ", request.operation);
#endif

      /* 取得したリクエストを処理する */
      if ((request.operation < 0) || (request.operation > NR_POSIX_SYSCALL))
	{
	  /* リクエスト要求にあるオペレーションは、サポートしていない */
	  error_response (&request, EP_NOSUP);
	}
      else
	{
#ifdef DEBUG
	  dbg_printf ("systemcall: %s\n", syscall_table[request.operation].name);
#endif

	   (*syscall_table[request.operation].syscall)(&request);
	}
#ifdef DEBUG
      dbg_printf ("posix: systemcall end.\n");
#endif
    }
  /* ここには来ない */
}
Beispiel #19
0
/**
 * Plugin for the IronBee ATS.
 *
 * Handles some ATS events.
 *
 * @param[in,out] contp Pointer to the continuation
 * @param[in,out] event Event from ATS
 * @param[in,out] edata Event data
 *
 * @returns status
 */
int ironbee_plugin(TSCont contp, TSEvent event, void *edata)
{
    ib_status_t rc;
    TSCont mycont;
    TSHttpTxn txnp = (TSHttpTxn) edata;
    TSHttpSsn ssnp = (TSHttpSsn) edata;
    tsib_txn_ctx *txndata;
    tsib_ssn_ctx *ssndata;
    tsib_hdr_outcome status;
    TSMutex ts_mutex = NULL;

    TSDebug("ironbee", "Entering ironbee_plugin with %d", event);
    switch (event) {

        /* CONNECTION */
        case TS_EVENT_HTTP_SSN_START:
            /* start of connection */
            /* But we can't initialize conn stuff here, because there's
             * no API to get the connection stuff required by ironbee
             * at this point.  So instead, intercept the first TXN
             *
             * what we can and must do: create a new contp whose
             * lifetime is our ssn
             */
            ts_mutex = TSMutexCreate();
            mycont = TSContCreate(ironbee_plugin, ts_mutex);
            TSHttpSsnHookAdd (ssnp, TS_HTTP_TXN_START_HOOK, mycont);
            ssndata = TSmalloc(sizeof(*ssndata));
            memset(ssndata, 0, sizeof(*ssndata));
            /* The only failure here is EALLOC, and if that happens
             * we're ****ed anyway
             */
            rc = ib_lock_create_malloc(&(ssndata->mutex));
            assert(rc == IB_OK);
            ssndata->contp = mycont;
            ssndata->ts_mutex = ts_mutex;
            TSContDataSet(mycont, ssndata);

            TSHttpSsnHookAdd (ssnp, TS_HTTP_SSN_CLOSE_HOOK, mycont);

            TSHttpSsnReenable (ssnp, TS_EVENT_HTTP_CONTINUE);
            break;

        case TS_EVENT_HTTP_TXN_START:
        {
            /* start of Request */
            /* First req on a connection, we set up conn stuff */
            ib_status_t  rc;
            ib_engine_t *ib = NULL;

            ssndata = TSContDataGet(contp);
            ib_lock_lock(ssndata->mutex);

            if (ssndata->iconn == NULL) {
                rc = tsib_manager_engine_acquire(&ib);
                if (rc == IB_DECLINED) {
                    /* OK, this means the manager is disabled deliberately,
                     * but otherwise all's well.  So this TXN
                     * gets processed without intervention from Ironbee
                     * and is invisble when our SSN_CLOSE hook runs.
                     */
                    ib_lock_unlock(ssndata->mutex);
                    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
                    TSDebug("ironbee", "Decline from engine manager");
                    break;
                }
                else if (rc != IB_OK) {
                    TSError("[ironbee] Failed to acquire engine: %s",
                            ib_status_to_string(rc));
                    goto noib_error;
                }
                if (ib != NULL) {
                    rc = ib_conn_create(ib, &ssndata->iconn, contp);
                    if (rc != IB_OK) {
                        TSError("[ironbee] ib_conn_create: %s",
                                ib_status_to_string(rc));
                        tsib_manager_engine_release(ib);
                        goto noib_error;
                    }

                    /* In the normal case, release the engine when the
                     * connection's memory pool is destroyed */
                    rc = ib_mm_register_cleanup(ssndata->iconn->mm,
                                                cleanup_ib_connection,
                                                ib);
                    if (rc != IB_OK) {
                        TSError("[ironbee] ib_mm_register_cleanup: %s",
                                ib_status_to_string(rc));
                        tsib_manager_engine_release(ib);
                        goto noib_error;
                    }

                    TSDebug("ironbee", "CONN CREATE: conn=%p", ssndata->iconn);
                    ssndata->txnp = txnp;
                    ssndata->txn_count = ssndata->closing = 0;

                    rc = ironbee_conn_init(ssndata);
                    if (rc != IB_OK) {
                        TSError("[ironbee] ironbee_conn_init: %s",
                                ib_status_to_string(rc));
                        goto noib_error;
                    }

                    TSContDataSet(contp, ssndata);
                    TSDebug("ironbee",
                            "ironbee_plugin: ib_state_notify_conn_opened()");
                    rc = ib_state_notify_conn_opened(ib, ssndata->iconn);
                    if (rc != IB_OK) {
                        TSError("[ironbee] Failed to notify connection opened: %s",
                                ib_status_to_string(rc));
                    }
                }
                else {
                    /* Use TSError where there's no ib or tx */
                    TSError("Ironbee: No ironbee engine!");
                    goto noib_error;
                }
            }

            /* create a txn cont (request ctx) and tx */
            txndata = TSmalloc(sizeof(*txndata));
            memset(txndata, 0, sizeof(*txndata));
            txndata->ssn = ssndata;
            txndata->txnp = txnp;

            rc = ib_tx_create(&txndata->tx, ssndata->iconn, txndata);
            if (rc != IB_OK) {
                TSError("[ironbee] Failed to create tx: %d", rc);
                tsib_manager_engine_release(ib);
                TSfree(txndata);
                goto noib_error;
            }

            ++ssndata->txn_count;
            ib_lock_unlock(ssndata->mutex);

            ib_log_debug_tx(txndata->tx,
                            "TX CREATE: conn=%p tx=%p id=%s txn_count=%d",
                            ssndata->iconn, txndata->tx, txndata->tx->id,
                            txndata->ssn->txn_count);

            mycont = TSContCreate(ironbee_plugin, ssndata->ts_mutex);
            TSContDataSet(mycont, txndata);

            TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, mycont);

            /* Hook to process responses */
            TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, mycont);

            /* Hook to process requests */
            TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, mycont);

            /* Create continuations for input and output filtering
             * to give them txn lifetime.
             */
            txndata->in_data_cont = TSTransformCreate(in_data_event, txnp);
            TSContDataSet(txndata->in_data_cont, txndata);

            txndata->out_data_cont = TSTransformCreate(out_data_event, txnp);
            TSContDataSet(txndata->out_data_cont, txndata);

            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
            break;

noib_error:
            ib_lock_unlock(ssndata->mutex);

            /* NULL txndata signals this to SEND_RESPONSE */
            mycont = TSContCreate(ironbee_plugin, ssndata->ts_mutex);
            TSContDataSet(mycont, NULL);

            TSError("[ironbee] Internal error initialising for transaction");
            TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, mycont);
            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
            break;
        }

        /* HTTP RESPONSE */
        case TS_EVENT_HTTP_READ_RESPONSE_HDR:
            txndata = TSContDataGet(contp);
            if (txndata->tx == NULL) {
                TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
                break;
            }

            /* Feed ironbee the headers if not done already. */
            if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_STARTED)) {
                status = process_hdr(txndata, txnp, &tsib_direction_server_resp);

                /* OK, if this was an HTTP 100 response, it's not the
                 * response we're interested in.  No headers have been
                 * sent yet, and no data will be sent until we've
                 * reached here again with the final response.
                 */
                if (status == HDR_HTTP_100) {
                    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
                    break;
                }
                // FIXME: Need to know if this fails as it (I think) means
                //        that the response did not come from the server and
                //        that ironbee should ignore it.
                /* I've not seen a fail here.  AFAICT if either the origin
                 * isn't responding or we're responding from cache. we
                 * never reach here in the first place.
                 */
            }

            /* If ironbee signalled an error while processing request body data,
             * this is the first opportunity to divert to an errordoc
             */
            if (HTTP_CODE(txndata->status)) {
                ib_log_debug_tx(txndata->tx,
                                "HTTP code %d contp=%p", txndata->status, contp);
                TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
                TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
                break;
            }

            /* If we're not going to inspect response body data 
             * we can bring forward notification of response-end
             * so we're in time to respond with an errordoc if Ironbee
             * wants to block in the response phase.
             *
             * This currently fails.  However, that appears to be because I
             * can't unset IB_TX_FINSPECT_RESBODY with InspectionEngineOptions
             */
            if (!ib_flags_all(txndata->tx->flags, IB_TX_FINSPECT_RESBODY)) {
                if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_STARTED) ) {
                    ib_state_notify_response_started(txndata->tx->ib, txndata->tx, NULL);
                }
                if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_FINISHED) ) {
                    ib_state_notify_response_finished(txndata->tx->ib, txndata->tx);
                }
                /* Test again for Ironbee telling us to block */
                if (HTTP_CODE(txndata->status)) {
                    TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
                    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
                    break;
                }
            }

            /* Flag that we're too late to divert to an error response */
            ib_tx_flags_set(txndata->tx, IB_TX_FCLIENTRES_STARTED);

            /* Normal execution.  Add output filter to inspect response. */
            TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK,
                             txndata->out_data_cont);
            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);

            break;

        /* Hook for processing response headers. */
        case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
            txndata = TSContDataGet(contp);
            if (txndata == NULL) {
                /* Ironbee is unavailable to help with our response. */
                internal_error_response(txnp);
                /* This contp isn't going through the normal flow. */
                TSContDestroy(contp);
                TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
                break;
            }

            /* If ironbee has sent us into an error response then
             * we came here in our error path, with nonzero status.
             */
            if (txndata->status != 0) {
                error_response(txnp, txndata);
            }

            /* Feed ironbee the headers if not done already. */
            if (!ib_flags_all(txndata->tx->flags, IB_TX_FRES_STARTED)) {
                if (process_hdr(txndata, txnp, &tsib_direction_client_resp) != HDR_OK) {
                    /* I think this is a shouldn't happen event, and that
                     * if it does we have an ironbee bug or misconfiguration.
                     * Log an error to catch if it happens in practice.
                     */
                    ib_log_error_tx(txndata->tx, "process_hdr returned error in send_response_hdr event");
                }
            }

            /* If there is an ironbee-generated response body, notify ironbee.
             *
             * NOTE: I do not see anywhere else to put this as the error body is
             *       just a buffer and not delivered via normal IO channels, so
             *       the error body will never get caught by an event.
             */
            if ((txndata->status != 0) && (txndata->err_body != NULL)) {
                const char *data = txndata->err_body;
                size_t data_length = txndata->err_body_len;
                ib_log_debug_tx(txndata->tx,
                        "error_response: calling ib_state_notify_response_body_data() %s:%d",
                        __FILE__, __LINE__);
                ib_state_notify_response_body_data(txndata->tx->ib,
                                                   txndata->tx,
                                                   data, data_length);
            }

            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
            break;

        /* HTTP REQUEST */
        case TS_EVENT_HTTP_READ_REQUEST_HDR:
            /* hook to examine output headers.  They're not available yet */
            TSHttpTxnHookAdd(txnp, TS_HTTP_PRE_REMAP_HOOK, contp);

            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
            break;

        /* hook for processing incoming request/headers
         * The OS_DNS hook is an alternative here.
         */
        case TS_EVENT_HTTP_PRE_REMAP:
        {
            int request_inspection_finished = 0;
            txndata = TSContDataGet(contp);
            assert ((txndata != NULL) && (txndata->tx != NULL));
            status = process_hdr(txndata, txnp, &tsib_direction_client_req);
            if (HDR_OUTCOME_IS_HTTP_OR_ERROR(status, txndata)) {
                if (status == HDR_HTTP_STATUS) {
                    ib_log_debug_tx(txndata->tx,
                                    "HTTP code %d contp=%p", txndata->status, contp);
                 }
                 else {
                    /* Ironbee set a status we don't handle.
                     * We returned EINVAL, but we also need housekeeping to
                     * avoid a crash in modhtp and log something bad.
                     */
                    ib_log_debug_tx(txndata->tx,
                                    "Internal error %d contp=%p", txndata->status, contp);
                    /* Ugly hack: notifications to stop modhtp bombing out */
                    request_inspection_finished = 1;
                }
            }
            else {
                /* Other nonzero statuses not supported */
                switch(status) {
                  case HDR_OK:
                    /* If we're not inspecting the Request body,
                     * we can bring forward notification of end-request
                     * so any header-only tests run on Request phase
                     * can abort the tx before opening a backend connection.
                     */
                    if (!ib_flags_all(txndata->tx->flags, IB_TX_FINSPECT_REQBODY)) {
                        request_inspection_finished = 1;
                    }
                    break;	/* All's well */
                  case HDR_HTTP_STATUS:
                    // FIXME: should we take the initiative here and return 500?
                    ib_log_error_tx(txndata->tx,
                                    "Internal error: ts-ironbee requested error but no error response set.");
                    break;
                  case HDR_HTTP_100:
                    /* This can't actually happen with current Trafficserver
                     * versions, as TS will generate a 400 error without
                     * reference to us.  But in case that changes in future ...
                     */
                    ib_log_error_tx(txndata->tx,
                                    "No request headers found.");
                    break;
                  default:
                    ib_log_error_tx(txndata->tx,
                                    "Unhandled state arose in handling request headers.");
                    break;
                }
            }
            if (request_inspection_finished) {
                if (!ib_flags_all(txndata->tx->flags, IB_TX_FREQ_STARTED) ) {
                    ib_state_notify_request_started(txndata->tx->ib, txndata->tx, NULL);
                }
                if (!ib_flags_all(txndata->tx->flags, IB_TX_FREQ_FINISHED) ) {
                    ib_state_notify_request_finished(txndata->tx->ib, txndata->tx);
                }
            }
            else {
                /* hook an input filter to watch data */
                TSHttpTxnHookAdd(txnp, TS_HTTP_REQUEST_TRANSFORM_HOOK,
                                 txndata->in_data_cont);
            }
            /* Flag that we can no longer prevent a request going to backend */
            ib_tx_flags_set(txndata->tx, IB_TX_FSERVERREQ_STARTED);

            /* Check whether Ironbee told us to block the request.
             * This could now come not just from process_hdr, but also
             * from a brought-forward notification if we aren't inspecting
             * a request body and notified request_finished.
             */
            if (HTTP_CODE(txndata->status)) {
                TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
                TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
            }
            else {
                TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
            }
            break;
        }


        /* CLEANUP EVENTS */
        case TS_EVENT_HTTP_TXN_CLOSE:
        {
            txndata = TSContDataGet(contp);

            TSContDestroy(txndata->out_data_cont);
            TSContDestroy(txndata->in_data_cont);
            TSContDataSet(contp, NULL);
            TSContDestroy(contp);
            if ( (txndata != NULL) && (txndata->tx != NULL) ) {
                ib_log_debug_tx(txndata->tx,
                                "TXN Close: %p", (void *)contp);
                tsib_txn_ctx_destroy(txndata);
            }
            TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
            break;
        }

        case TS_EVENT_HTTP_SSN_CLOSE:
            TSDebug("ironbee", "SSN Close: %p", (void *)contp);
            tsib_ssn_ctx_destroy(TSContDataGet(contp));
            tsib_manager_engine_cleanup();
            TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE);
            break;

        case TS_EVENT_MGMT_UPDATE:
        {
            TSDebug("ironbee", "Management update");
            ib_status_t  rc;
            rc = tsib_manager_engine_create();
            if (rc != IB_OK) {
                TSError("[ironbee] Error creating new engine: %s",
                        ib_status_to_string(rc));
            }
            break;
        }

        /* if we get here we've got a bug */
        default:
            TSError("[ironbee] *** Unhandled event %d in ironbee_plugin.", event);
            break;
    }

    return 0;
}
static void solve_gains(int *p_counter, double dx, int n, int nb_bands, double *p_best_gains, double *p_best_error, t_mdrc_gains *p_mdrc_gains, double *p_weigthing, double error_max, int counter_max)
{
    double gains[NB_BANDS_MAX], x1[NB_BANDS_MAX], x2[NB_BANDS_MAX], x3[NB_BANDS_MAX], x4[NB_BANDS_MAX], x5[NB_BANDS_MAX], error;
    int    i1, i2, i3, i4, i5;

    memcpy(gains, p_best_gains, nb_bands * sizeof(double));
    for(i1 = -n; i1 <= n; i1++)
    {
        memcpy(x1, gains, nb_bands * sizeof(double));
        x1[0] = gains[0] * pow(1.0 + dx, i1);
        if(nb_bands >= 2)
        {
            memcpy(x2, x1, nb_bands * sizeof(double));
            for(i2 = -n; i2 <= n; i2++)
            {
                x2[1] = x1[1] * pow(1.0 + dx, i2);
                if(nb_bands >= 3)
                {
                    memcpy(x3, x2, nb_bands * sizeof(double));
                    for(i3 = -n; i3 <= n; i3++)
                    {
                        x3[2] = x2[2] * pow(1.0 + dx, i3);
                        if(nb_bands >= 4)
                        {
                            memcpy(x4, x3, nb_bands * sizeof(double));
                            for(i4 = -n; i4 <= n; i4++)
                            {
                                x4[3] = x3[3] * pow(1.0 + dx, i4);
                                if(nb_bands >= 5)
                                {
                                    memcpy(x5, x4, nb_bands * sizeof(double));
                                    for(i5 = -n; i5 <= n; i5++)
                                    {
                                        x5[4] = x4[4] * pow(1.0 + dx, i5);
                                        error = error_response(p_mdrc_gains, x5, nb_bands, p_weigthing);
                                        (*p_counter)++;
                                        if(error < *p_best_error)
                                        {
                                            memcpy(p_best_gains, x5, nb_bands * sizeof(double));
                                            *p_best_error = error;
                                            display_result(*p_counter, error, dx);
                                        }
                                    }
                                    memcpy(gains, p_best_gains, nb_bands * sizeof(double));
                                    error = *p_best_error;
                                    if((error < error_max) || (*p_counter > counter_max))
                                    {
                                        return;
                                    }
                                }
                                else
                                {
                                    error = error_response(p_mdrc_gains, x4, nb_bands, p_weigthing);
                                    (*p_counter)++;
                                    if(error < *p_best_error)
                                    {
                                        memcpy(p_best_gains, x4, nb_bands * sizeof(double));
                                        *p_best_error = error;
                                        display_result(*p_counter, error, dx);
                                    }
                                }
                            }
                            memcpy(gains, p_best_gains, nb_bands * sizeof(double));
                            error = *p_best_error;
                            if((error < error_max) || (*p_counter > counter_max))
                            {
                                return;
                            }
                        }
                        else
                        {
                            error = error_response(p_mdrc_gains, x3, nb_bands, p_weigthing);
                            (*p_counter)++;
                            if(error < *p_best_error)
                            {
                                memcpy(p_best_gains, x3, nb_bands * sizeof(double));
                                *p_best_error = error;
                                display_result(*p_counter, error, dx);
                            }
                        }
                    }
                    memcpy(gains, p_best_gains, nb_bands * sizeof(double));
                    error = *p_best_error;
                    if((error < error_max) || (*p_counter > counter_max))
                    {
                        return;
                    }
                }
                else
                {
                    error = error_response(p_mdrc_gains, x2, nb_bands, p_weigthing);
                    (*p_counter)++;
                    if(error < *p_best_error)
                    {
                        memcpy(p_best_gains, x2, nb_bands * sizeof(double));
                        *p_best_error = error;
                        display_result(*p_counter, error, dx);
                    }
                }
            }
            memcpy(gains, p_best_gains, nb_bands * sizeof(double));
            error = *p_best_error;
            if((error < error_max) || (*p_counter > counter_max))
            {
                return;
            }
        }
        else
        {
            error = error_response(p_mdrc_gains, x1, nb_bands, p_weigthing);
            (*p_counter)++;
            if(error < *p_best_error)
            {
                memcpy(p_best_gains, x1, nb_bands * sizeof(double));
                *p_best_error = error;
                display_result(*p_counter, error, dx);
            }
        }
    }
}