Пример #1
0
/*-------------------------------------------------------------------------
  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);
  }
}
Пример #2
0
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;
}
Пример #4
0
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);
    }
}
Пример #5
0
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;
}
Пример #6
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;
}
Пример #7
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;
  }
}
Пример #8
0
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);
}
Пример #9
0
/** 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;
}
Пример #10
0
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++;
	}
}
Пример #11
0
/* 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;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #14
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);
}
Пример #15
0
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);
}
Пример #16
0
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);
}
Пример #17
0
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;
}
Пример #18
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;
}
Пример #19
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);
}
Пример #20
0
// 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;
}
Пример #22
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);
}
Пример #23
0
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;
}
Пример #24
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;
}
Пример #25
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);
}
Пример #26
0
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;
}
Пример #28
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;
}
Пример #29
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;
}
Пример #30
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));
    }
}