/*------------------------------------------------------------------------- cont_data_destroy Deallocate ContData structure associated to a transaction Input: data structure to deallocate Output: Return Value: none -------------------------------------------------------------------------*/ static void cont_data_destroy(ContData * data) { TSDebug(DBG_TAG, "Destroying continuation data"); if (data) { TSAssert(data->magic == MAGIC_ALIVE); if (data->output_reader) { TSIOBufferReaderFree(data->output_reader); data->output_reader = NULL; } if (data->output_buffer) { TSIOBufferDestroy(data->output_buffer); data->output_buffer = NULL; } if (data->psi_reader) { TSIOBufferReaderFree(data->psi_reader); data->psi_reader = NULL; } if (data->psi_buffer) { TSIOBufferDestroy(data->psi_buffer); data->psi_buffer = NULL; } data->magic = MAGIC_DEAD; TSfree(data); } }
static int ts_lua_http_set_cache_lookup_url(lua_State *L) { const char *url; size_t url_len; ts_lua_http_ctx *http_ctx; GET_HTTP_CONTEXT(http_ctx, L); url = luaL_checklstring(L, 1, &url_len); if (url && url_len) { const char *start = url; const char *end = url + url_len; TSMLoc new_url_loc; if (TSUrlCreate(http_ctx->client_request_bufp, &new_url_loc) == TS_SUCCESS && TSUrlParse(http_ctx->client_request_bufp, new_url_loc, &start, end) == TS_PARSE_DONE && TSHttpTxnCacheLookupUrlSet(http_ctx->txnp, http_ctx->client_request_bufp, new_url_loc) == TS_SUCCESS) { TSDebug(TS_LUA_DEBUG_TAG, "Set cache lookup URL"); } else { TSError("[ts_lua] Failed to set cache lookup URL"); } } return 0; }
static bool prune_config(invalidate_t **i) { invalidate_t *iptr, *ilast; time_t now; bool pruned = false; now = time(NULL); if (*i) { iptr = *i; ilast = NULL; while (iptr) { if (difftime(iptr->expiry, now) < 0) { TSDebug(LOG_PREFIX, "Removing %s expiry: %d now: %d", iptr->regex_text, (int)iptr->expiry, (int)now); if (ilast) { ilast->next = iptr->next; free_invalidate_t(iptr); iptr = ilast->next; } else { *i = iptr->next; free_invalidate_t(iptr); iptr = *i; } pruned = true; } else { ilast = iptr; iptr = iptr->next; } } } return pruned; }
static void parse_response(StateInfo *state) { TSIOBufferBlock block; TSParseResult pr = TS_PARSE_CONT; int64_t avail; char *start; block = TSIOBufferReaderStart(state->resp_io_buf_reader); while ((pr == TS_PARSE_CONT) && (block != NULL)) { start = (char *) TSIOBufferBlockReadStart(block, state->resp_io_buf_reader, &avail); if (avail > 0) { pr = TSHttpHdrParseResp(state->resp_info->parser, state->resp_info->buf, state->resp_info->http_hdr_loc, (const char **) &start, (const char *) (start + avail)); } block = TSIOBufferBlockNext(block); } if (pr != TS_PARSE_CONT) { state->resp_info->status = TSHttpHdrStatusGet(state->resp_info->buf, state->resp_info->http_hdr_loc); state->resp_info->parsed = true; TSDebug(PLUGIN_NAME, "HTTP Status: %d", state->resp_info->status); } }
static int ssn_handler(TSCont contp, TSEvent event, void *edata) { TSHttpSsn ssnp; TSHttpTxn txnp; switch (event) { case TS_EVENT_HTTP_SSN_START: ssnp = (TSHttpSsn)edata; handle_session(ssnp, contp); TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE); return 0; case TS_EVENT_HTTP_TXN_START: txnp = (TSHttpTxn)edata; txn_handler(txnp, contp); TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: TSDebug("tag_session", "In the default case: event = %d", event); break; } return 0; }
static int transform_handler(TSCont contp, TSEvent event, void *edata) { /* Check to see if the transformation has been closed by a call to TSVConnClose. */ if (TSVConnClosedGet(contp)) { TSDebug("strans", "transformation closed"); transform_destroy(contp); return 0; } else { TransformData *data; int val = 0; data = (TransformData *)TSContDataGet(contp); if (data == NULL) { TSError("Didn't get Continuation's Data. Ignoring Event.."); return 0; } TSDebug("strans", "transform handler event [%d], data->state = [%d]", event, data->state); do { switch (data->state) { case STATE_BUFFER: val = transform_buffer_event(contp, data, event, edata); break; case STATE_CONNECT: val = transform_connect_event(contp, data, event, edata); break; case STATE_WRITE: val = transform_write_event(contp, data, event, edata); break; case STATE_READ_STATUS: val = transform_read_status_event(contp, data, event, edata); break; case STATE_READ: val = transform_read_event(contp, data, event, edata); break; case STATE_BYPASS: val = transform_bypass_event(contp, data, event, edata); break; } } while (val); } return 0; }
/*------------------------------------------------------------------------- strsearch_ioreader Looks for string pattern in an iobuffer Input: reader reader on a iobuffer pattern string to look for (nul terminated) Output: nparse number of chars scanned, excluding the matching pattern Return Value: STR_SUCCESS if pattern found STR_PARTIAL if pattern found partially STR_FAIL if pattern not found -------------------------------------------------------------------------*/ static StrOperationResult strsearch_ioreader(TSIOBufferReader reader, const char *pattern, int *nparse) { int index = 0; TSIOBufferBlock block = TSIOBufferReaderStart(reader); int slen = strlen(pattern); if (slen <= 0) { return STR_FAIL; } *nparse = 0; /* Loop thru each block while we've not yet found the pattern */ while ((block != NULL) && (index < slen)) { int64_t blocklen; const char *blockptr = TSIOBufferBlockReadStart(block, reader, &blocklen); const char *ptr; for (ptr = blockptr; ptr < blockptr + blocklen; ptr++) { (*nparse)++; if (*ptr == pattern[index]) { index++; if (index == slen) { break; } } else { index = 0; } } /* Parse next block */ block = TSIOBufferBlockNext(block); } *nparse -= index; /* Adjust nparse so it doesn't include matching chars */ if (index == slen) { TSDebug(DBG_TAG, "strfind: match for %s at position %d", pattern, *nparse); return STR_SUCCESS; } else if (index > 0) { TSDebug(DBG_TAG, "strfind: partial match for %s at position %d", pattern, *nparse); return STR_PARTIAL; } else { TSDebug(DBG_TAG, "strfind no match for %s", pattern); return STR_FAIL; } }
void TSPluginInit(int argc, const char *argv[]) { TSPluginRegistrationInfo info; char *end; int tmp; info.plugin_name = PLUGIN_NAME; info.vendor_name = "Apache Software Foundation"; info.support_email = "*****@*****.**"; if (TSPluginRegister(&info) != TS_SUCCESS) { TSError("[%s] Plugin registration failed", PLUGIN_NAME); goto error; } /* default value */ accept_port = 4666; server_port = 4666; if (argc < 3) { TSDebug(PLUGIN_NAME, "Usage: protocol.so <accept_port> <server_port>. Using default ports accept=%d server=%d", accept_port, server_port); } else { tmp = strtol(argv[1], &end, 10); if (*end == '\0') { accept_port = tmp; TSDebug(PLUGIN_NAME, "using accept_port %d", accept_port); } else { TSError("[%s] Wrong argument for accept_port, using default port %d", PLUGIN_NAME, accept_port); } tmp = strtol(argv[2], &end, 10); if (*end == '\0') { server_port = tmp; TSDebug(PLUGIN_NAME, "using server_port %d", server_port); } else { TSError("[%s] Wrong argument for server_port, using default port %d", PLUGIN_NAME, server_port); } } protocol_init(accept_port, server_port); error: TSError("[%s] Plugin not initialized", PLUGIN_NAME); }
/** Create and return top-level cont with no transient data * Sets up engine manager and kill-or-continue txn hook before launching * potentially-slow mainconfiguration in separate thread. */ static ib_status_t tsib_pre_init(TSCont *contp) { int rv; ib_status_t rc; TSCont cont; assert(contp != NULL); /* create a cont to fend off traffic while we read config */ *contp = cont = TSContCreate(ironbee_plugin, NULL); if (cont == NULL) { TSError("[ironbee] failed to create initial continuation: disabled"); return IB_EUNKNOWN; } if (module_data.allow_at_startup) { /* SSN_START doesn't use contdata; READ_REQUEST_HDR only needs non-null flag. * Using &module_data might let us clean up some tsib_api stuff in future. */ TSContDataSet(cont, &module_data); } else { /* NULL contdata signals the READ_REQUEST_HDR hook to reject requests */ TSContDataSet(cont, NULL); } TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, cont); if (!module_data.log_disable) { /* success is documented as TS_LOG_ERROR_NO_ERROR but that's undefined. * It's actually a TS_SUCCESS (proxy/InkAPI.cc line 6641). */ printf("Logging to \"%s\"\n", module_data.log_file); rv = TSTextLogObjectCreate(module_data.log_file, TS_LOG_MODE_ADD_TIMESTAMP, &module_data.logger); if (rv != TS_SUCCESS) { TSError("[ironbee] Error creating log file."); return IB_EUNKNOWN; } } /* Initialize IronBee (including util) */ rc = ib_initialize(); if (rc != IB_OK) { TSError("[ironbee] Error initializing IronBee: %s", ib_status_to_string(rc)); return rc; } /* Create the IronBee engine manager */ TSDebug("ironbee", "Creating IronBee engine manager"); rc = ib_manager_create(&(module_data.manager), /* Engine Manager */ &ibplugin, /* Server object */ module_data.max_engines); /* Default max */ if (rc != IB_OK) { TSError("[ironbee] Error creating IronBee engine manager: %s", ib_status_to_string(rc)); } return rc; }
static void parseIps6(config_t* config, char* ipStr) { char buffer[STR_BUFFER_SIZE]; char *p, *tok1, *tok2, *ip; int i, mask; char ip_port_text_buffer[INET6_ADDRSTRLEN]; if(!ipStr) { config->ip6Count = 1; ip = config->allowIps6 = TSmalloc(5); inet_pton(AF_INET, DEFAULT_IP6, ip); ip[8] = 64; return; } strcpy(buffer, ipStr); p = buffer; while(strtok_r(p, ", \n", &p)) { config->ip6Count++; } if(!config->ip6Count) { return; } config->allowIps6 = TSmalloc(9*config->ip6Count); // 4 bytes for ip + 1 for bit mask strcpy(buffer, ipStr); p = buffer; i = 0; while((tok1 = strtok_r(p, ", \n", &p))) { TSDebug(PLUGIN_TAG, "%d) parsing: %s", i+1,tok1); tok2 = strtok_r(tok1, "/", &tok1); ip = config->allowIps6+(9*i); if(!inet_pton(AF_INET, tok2, ip)) { TSDebug(PLUGIN_TAG, "%d) skipping: %s", i+1,tok1); continue; } tok2 = strtok_r(tok1, "/", &tok1); if(!tok2) { mask = 64; } else { mask = atoi(tok2); } ip[8] = mask; TSDebug(PLUGIN_TAG, "%d) adding netmask: %s/%d", i+1, inet_ntop(AF_INET6,ip,ip_port_text_buffer,INET6_ADDRSTRLEN),ip[8]); i++; } }
/* Read-request header continuation, used to kick off the server intercept if necessary */ static int acme_hook(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata) { TSMBuffer reqp; TSMLoc hdr_loc = NULL, url_loc = NULL; TSCont icontp; AcmeState *my_state; TSHttpTxn txnp = (TSHttpTxn)edata; TSDebug(PLUGIN_NAME, "kicking off ACME hook"); if ((TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) && (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc))) { int path_len = 0; const char *path = TSUrlPathGet(reqp, url_loc, &path_len); /* Short circuit the / path, common case */ if (!path || path_len < (int)(strlen(ACME_WK_PATH) + 2) || *path != '.' || memcmp(path, ACME_WK_PATH, strlen(ACME_WK_PATH))) { TSDebug(PLUGIN_NAME, "skipping URL path = %.*s", path_len, path); goto cleanup; } TSSkipRemappingSet(txnp, 1); /* not strictly necessary, but speed is everything these days */ /* This request is for us -- register our intercept */ icontp = TSContCreate(acme_intercept, TSMutexCreate()); my_state = make_acme_state(); open_acme_file(my_state, path + strlen(ACME_WK_PATH), path_len - strlen(ACME_WK_PATH)); TSContDataSet(icontp, my_state); TSHttpTxnIntercept(icontp, txnp); TSDebug(PLUGIN_NAME, "created intercept hook"); } cleanup: if (url_loc) { TSHandleMLocRelease(reqp, hdr_loc, url_loc); } if (hdr_loc) { TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
static int request_buffer_plugin(TSCont contp, TSEvent event, void *edata) { TSDebug(PLUGIN_NAME, "request_buffer_plugin starting, event[%d]", event); TSHttpTxn txnp = (TSHttpTxn)(edata); if (event == TS_EVENT_HTTP_REQUEST_BUFFER_COMPLETE) { int len = 0; char *body = request_body_get(txnp, &len); TSDebug(PLUGIN_NAME, "request_buffer_plugin gets the request body with length[%d]", len); TSfree(body); TSContDestroy(contp); } else { ink_assert(0); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
static int config_handler(TSCont cont, TSEvent event, void *edata) { config_holder_t *config_holder; TSDebug(PLUGIN_TAG, "In config Handler"); config_holder = (config_holder_t *) TSContDataGet(cont); load_config_file(config_holder); return 0; }
static void stat_add(char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex create_mutex) { int stat_id = -1; ENTRY search, *result = NULL; static __thread struct hsearch_data stat_cache; static __thread bool hash_init = false; if (unlikely(!hash_init)) { hcreate_r(TS_MAX_API_STATS << 1, &stat_cache); hash_init = true; TSDebug(DEBUG_TAG, "stat cache hash init"); } search.key = name; search.data = 0; hsearch_r(search, FIND, &result, &stat_cache); if (unlikely(result == NULL)) { // This is an unlikely path because we most likely have the stat cached // so this mutex won't be much overhead and it fixes a race condition // in the RecCore. Hopefully this can be removed in the future. TSMutexLock(create_mutex); if (TS_ERROR == TSStatFindName((const char *) name, &stat_id)) { stat_id = TSStatCreate((const char *) name, TS_RECORDDATATYPE_INT, persist_type, TS_STAT_SYNC_SUM); if (stat_id == TS_ERROR) TSDebug(DEBUG_TAG, "Error creating stat_name: %s", name); else TSDebug(DEBUG_TAG, "Created stat_name: %s stat_id: %d", name, stat_id); } TSMutexUnlock(create_mutex); if (stat_id >= 0) { search.key = TSstrdup(name); search.data = (void *) ((intptr_t) stat_id); hsearch_r(search, ENTER, &result, &stat_cache); TSDebug(DEBUG_TAG, "Cached stat_name: %s stat_id: %d", name, stat_id); } } else stat_id = (int) ((intptr_t) result->data); if (likely(stat_id >= 0)) TSStatIntIncrement(stat_id, amount); else TSDebug(DEBUG_TAG, "stat error! stat_name: %s stat_id: %d", name, stat_id); }
static void ironbee_plugin_ssn_close(TSCont contp, TSHttpSsn ssnp) { assert(contp != NULL); TSDebug("ironbee", "SSN Close: %p", (void *)contp); tsib_ssn_ctx_destroy(TSContDataGet(contp)); tsib_manager_engine_cleanup(); TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE); }
static void txn_handler(TSHttpTxn txnp, TSCont contp) { int64_t num_txns = 0; INKStatIncrement(transaction_count); num_txns = INKStatIntGet(transaction_count); TSDebug("tag_session", "The number of transactions is %" PRId64, num_txns); }
static int ts_lua_debug(lua_State * L) { const char *msg; msg = luaL_checkstring(L, 1); TSDebug(TS_LUA_DEBUG_TAG, msg, NULL); return 0; }
static int free_handler(TSCont cont, TSEvent event, void *edata) { config_t *config; TSDebug(PLUGIN_TAG, "Freeing old config"); config = (config_t *) TSContDataGet(cont); delete_config(config); TSContDestroy(cont); return 0; }
static void transform_add(TSHttpTxn txnp) { TSVConn connp; TSDebug("null-transform", "Entering transform_add()"); connp = TSTransformCreate(null_transform, txnp); TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp); }
// This serves to consume all the data that arrives. If it's not consumed the tunnel gets stalled // and the transaction doesn't complete. Other things could be done with the data, accessible via // the IO buffer @a reader, such as writing it to disk to make an externally accessible copy. static int client_reader(TSCont contp, TSEvent event, void *edata) { SinkData *data = TSContDataGet(contp); // If we got closed, we're done. if (TSVConnClosedGet(contp)) { TSfree(data); TSContDestroy(contp); return 0; } TSVIO input_vio = TSVConnWriteVIOGet(contp); if (!data) { data = TSmalloc(sizeof(SinkData)); data->total = 0; TSContDataSet(contp, data); } switch (event) { case TS_EVENT_ERROR: TSDebug(PLUGIN_NAME, "Error event"); TSContCall(TSVIOContGet(input_vio), TS_EVENT_ERROR, input_vio); break; case TS_EVENT_VCONN_READ_COMPLETE: TSDebug(PLUGIN_NAME, "READ_COMPLETE"); break; case TS_EVENT_VCONN_READ_READY: case TS_EVENT_IMMEDIATE: TSDebug(PLUGIN_NAME, "Data event - %s", event == TS_EVENT_IMMEDIATE ? "IMMEDIATE" : "READ_READY"); // Look for data and if we find any, consume. if (TSVIOBufferGet(input_vio)) { TSIOBufferReader reader = TSVIOReaderGet(input_vio); int64_t n = TSIOBufferReaderAvail(reader); if (n > 0) { TSIOBufferReaderConsume(reader, n); TSVIONDoneSet(input_vio, TSVIONDoneGet(input_vio) + n); data->total += n; // internal accounting so we can print the value at the end. TSDebug(PLUGIN_NAME, "Consumed %" PRId64 " bytes", n); } if (TSVIONTodoGet(input_vio) > 0) { // signal that we can accept more data. TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_READY, input_vio); } else { TSDebug(PLUGIN_NAME, "send WRITE_COMPLETE"); TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_COMPLETE, input_vio); } } else { // buffer gone, we're done. TSDebug(PLUGIN_NAME, "upstream buffer disappeared - %" PRId64 " bytes", data->total); } break; default: TSDebug(PLUGIN_NAME, "unhandled event %d", event); break; } return 0; }
static int config_handler(TSCont cont, TSEvent event, void *edata) { plugin_state_t *pstate; invalidate_t *i, *iptr; TSCont free_cont; bool updated; TSMutex mutex; mutex = TSContMutexGet(cont); TSMutexLock(mutex); TSDebug(LOG_PREFIX, "In config Handler"); pstate = (plugin_state_t *)TSContDataGet(cont); i = copy_config(pstate->invalidate_list); updated = prune_config(&i); updated = load_config(pstate, &i) || updated; if (updated) { list_config(pstate, i); iptr = __sync_val_compare_and_swap(&(pstate->invalidate_list), pstate->invalidate_list, i); if (iptr) { free_cont = TSContCreate(free_handler, TSMutexCreate()); TSContDataSet(free_cont, (void *)iptr); TSContScheduleOnPool(free_cont, FREE_TMOUT, TS_THREAD_POOL_TASK); } } else { TSDebug(LOG_PREFIX, "No Changes"); if (i) { free_invalidate_t_list(i); } } TSMutexUnlock(mutex); // Don't reschedule for TS_EVENT_MGMT_UPDATE if (event == TS_EVENT_TIMEOUT) { TSContScheduleOnPool(cont, CONFIG_TMOUT, TS_THREAD_POOL_TASK); } return 0; }
static void handle_session(TSHttpSsn ssnp, TSCont contp) { int64_t num_ssn = 0; INKStatIncrement(session_count); num_ssn = INKStatIntGet(session_count); TSDebug("tag_session", "The number of sessions is %" PRId64, num_ssn); TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_START_HOOK, contp); }
static int ts_lua_debug(lua_State *L) { const char *msg; size_t len = 0; msg = luaL_checklstring(L, 1, &len); TSDebug(TS_LUA_DEBUG_TAG, "%.*s", (int)len, msg); return 0; }
static int transform_connect(TSCont contp, TransformData *data) { TSAction action; int content_length; struct sockaddr_in ip_addr; data->state = STATE_CONNECT; content_length = TSIOBufferReaderAvail(data->input_reader); if (content_length >= 0) { data->content_length = content_length; data->content_length = htonl(data->content_length); /* Prepend the content length to the buffer. * If we decide to not send the content to the transforming * server then we need to make sure and skip input_reader * over the content length. */ { TSIOBuffer temp; TSIOBufferReader tempReader; temp = TSIOBufferCreate(); tempReader = TSIOBufferReaderAlloc(temp); TSIOBufferWrite(temp, (const char *)&content_length, sizeof(int)); TSIOBufferCopy(temp, data->input_reader, content_length, 0); TSIOBufferReaderFree(data->input_reader); TSIOBufferDestroy(data->input_buf); data->input_buf = temp; data->input_reader = tempReader; } } else { TSError("[%s] TSIOBufferReaderAvail returns TS_ERROR", PLUGIN_NAME); return 0; } /* TODO: This only supports IPv4, probably should be changed at some point, but it's an example ... */ memset(&ip_addr, 0, sizeof(ip_addr)); ip_addr.sin_family = AF_INET; ip_addr.sin_addr.s_addr = server_ip; /* Should be in network byte order */ ip_addr.sin_port = server_port; TSDebug(PLUGIN_NAME, "net connect."); action = TSNetConnect(contp, (struct sockaddr const *)&ip_addr); if (!TSActionDone(action)) { data->pending_action = action; } return 0; }
/* This is where we start the PURGE events, setting up the transaction to fail, and bump the generation ID, and finally save the state. */ static void update_purge_state(PurgeInstance *purge) { FILE *file; TSMutexLock(purge->lock); ++purge->gen_id; TSDebug(PLUGIN_NAME, "Bumping the Generation ID to %" PRId64 " for %s", purge->gen_id, purge->id); if ((file = fopen(purge->state_file, "w"))) { TSDebug(PLUGIN_NAME, "\tsaving state to %s", purge->state_file); fprintf(file, "%" PRId64 "", purge->gen_id); fclose(file); } else { TSError("[%s] Unable to save state to file %s: errno=%d", PLUGIN_NAME, purge->state_file, errno); } TSMutexUnlock(purge->lock); }
static int main_hook(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; TSDebug(PLUGIN_NAME, "Checking transaction"); switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: if (enable_agent_check(txnp)) { TSDebug(PLUGIN_NAME, "Adding data sink to transaction"); client_add(txnp); } break; default: break; } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; }
static int free_handler(TSCont cont, TSEvent event, void *edata) { invalidate_t *iptr; TSDebug(LOG_PREFIX, "Freeing old config"); iptr = (invalidate_t *)TSContDataGet(cont); free_invalidate_t_list(iptr); TSContDestroy(cont); return 0; }
static int transform_connect_event(TSCont contp, TransformData * data, TSEvent event, void *edata) { switch (event) { case TS_EVENT_NET_CONNECT: TSDebug("strans", "connected"); data->pending_action = NULL; data->server_vc = (TSVConn) edata; return transform_write(contp, data); case TS_EVENT_NET_CONNECT_FAILED: TSDebug("strans", "connect failed"); data->pending_action = NULL; return transform_bypass(contp, data); default: break; } return 0; }
static int transform_plugin(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp = (TSHttpTxn) edata; TSDebug("null-transform", "Entering transform_plugin()"); switch (event) { case TS_EVENT_HTTP_READ_RESPONSE_HDR: TSDebug("null-transform", "\tEvent is TS_EVENT_HTTP_READ_RESPONSE_HDR"); if (transformable(txnp)) { transform_add(txnp); } TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); return 0; default: break; } return 0; }
static void ironbee_plugin_mgmt_update(TSCont contp) { assert(contp != NULL); 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)); } }