Example #1
0
void
SPT_EventAdd(int efd, struct septum *st)
{
	int r, errnum;

	(void)errnum;

#if defined(HAVE_EPOLL_CTL)
	st->ev.data.ptr = st;
	st->ev.events = EPOLLERR;
	if (st->events & SEPTUM_WANT_READ)
		st->ev.events = EPOLLIN | EPOLLPRI;
	else if (st->events & SEPTUM_WANT_WRITE)
		st->ev.events = EPOLLOUT;
	else
		WRONG("Unknown event type");
	r = epoll_ctl(efd, EPOLL_CTL_ADD, st->fd, &st->ev);
	errnum = errno;
	AZ(r);
#elif defined(HAVE_KQUEUE)
	st->ev.udata = st;
	if (st->events & SEPTUM_WANT_READ)
		EV_SET(&st->ev, st->fd, EVFILT_READ, EV_ADD, 0, 0, st);
	else if (st->events & SEPTUM_WANT_WRITE)
		EV_SET(&st->ev, st->fd, EVFILT_WRITE, EV_ADD, 0, 0, st);
	else
		WRONG("Unknown event type");
	r = kevent(efd, &st->ev, 1, NULL, 0, NULL);
	errnum = errno;
	AZ(r);
#else
#error "unsupported event model"
#endif
}
Example #2
0
static struct http *
VRT_selecthttp(const struct vrt_ctx *ctx, enum gethdr_e where)
{
	struct http *hp;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	switch (where) {
	case HDR_REQ:
		hp = ctx->http_req;
		break;
	case HDR_BEREQ:
		hp = ctx->http_bereq;
		break;
	case HDR_BERESP:
		hp = ctx->http_beresp;
		break;
	case HDR_RESP:
		hp = ctx->http_resp;
		break;
#if !defined(VRT_MAJOR_VERSION) || (VRT_MAJOR_VERSION < 2)
	case HDR_OBJ:
		hp = ctx->http_obj;
		break;
#endif
	default:
		WRONG("VRT_selecthttp 'where' invalid");
	}
	return (hp);
}
static ssize_t
ved_decode_len(struct req *req, uint8_t **pp)
{
	uint8_t *p;
	ssize_t l;

	p = *pp;
	switch (*p & 15) {
	case 1:
		l = p[1];
		p += 2;
		break;
	case 2:
		l = vbe16dec(p + 1);
		p += 3;
		break;
	case 8:
		l = vbe64dec(p + 1);
		p += 9;
		break;
	default:
		VSLb(req->vsl, SLT_Error,
		    "ESI-corruption: Illegal Length %d %d\n", *p, (*p & 15));
		WRONG("ESI-codes: illegal length");
	}
	*pp = p;
	assert(l > 0);
	return (l);
}
Example #4
0
static enum req_fsm_nxt
cnt_miss(struct worker *wrk, struct req *req)
{

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
	AZ(req->obj);

	VCL_miss_method(req->vcl, wrk, req, NULL, req->http->ws);
	switch (wrk->handling) {
	case VCL_RET_FETCH:
		wrk->stats.cache_miss++;
		VBF_Fetch(wrk, req, req->objcore, NULL, VBF_NORMAL);
		req->req_step = R_STP_FETCH;
		return (REQ_FSM_MORE);
	case VCL_RET_ERROR:
		req->req_step = R_STP_ERROR;
		break;
	case VCL_RET_RESTART:
		req->req_step = R_STP_RESTART;
		break;
	case VCL_RET_PASS:
		req->req_step = R_STP_PASS;
		break;
	default:
		WRONG("Illegal return from vcl_miss{}");
	}
	free(req->vary_b);
	AZ(HSH_DerefObjCore(&wrk->stats, &req->objcore));
	return (REQ_FSM_MORE);
}
Example #5
0
static void
child_malloc_fail(void *p, const char *s)
{
	VSL(SLT_Error, 0, "MALLOC ERROR: %s (%p)", s, p);
	fprintf(stderr, "MALLOC ERROR: %s (%p)\n", s, p);
	WRONG("Malloc Error");
}
Example #6
0
static void
vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1)
{
	char *p;
	int i;

	for (i = 0; i < ind; i++)
		VSB_cat(d, " ");
	p = VSB_data(e1->vsb);
	while (*p != '\0') {
		if (*p == '\n') {
			VSB_putc(d, '\n');
			if (p[1] != '\0') {
				for (i = 0; i < ind; i++)
					VSB_cat(d, " ");
			}
			p++;
			continue;
		}
		if (*p != '\v') {
			VSB_putc(d, *p);
			p++;
			continue;
		}
		p++;
		switch(*p) {
		case '+': ind += 2; break;
		case '-': ind -= 2; break;
		default:
			WRONG("Illegal format in VCC expression");
		}
		p++;
	}
}
Example #7
0
static enum req_fsm_nxt
cnt_pass(struct worker *wrk, struct req *req)
{

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	AN(req->vcl);
	AZ(req->objcore);

	VCL_pass_method(req->vcl, wrk, req, NULL, NULL);
	switch (wrk->handling) {
	case VCL_RET_SYNTH:
		req->req_step = R_STP_SYNTH;
		break;
	case VCL_RET_RESTART:
		req->req_step = R_STP_RESTART;
		break;
	case VCL_RET_FETCH:
		wrk->stats->s_pass++;
		req->objcore = HSH_Private(wrk);
		CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
		VBF_Fetch(wrk, req, req->objcore, NULL, VBF_PASS);
		req->req_step = R_STP_FETCH;
		break;
	default:
		WRONG("Illegal return from cnt_pass{}");
	}
	return (REQ_FSM_MORE);
}
Example #8
0
enum req_fsm_nxt
CNT_Request(struct worker *wrk, struct req *req)
{
	enum req_fsm_nxt nxt;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);

	/*
	 * Possible entrance states
	 */
	assert(
	    req->req_step == R_STP_LOOKUP ||
	    req->req_step == R_STP_RECV);

	AN(req->vsl->wid & VSL_CLIENTMARKER);

	req->wrk = wrk;
	wrk->vsl = req->vsl;

	for (nxt = REQ_FSM_MORE; nxt == REQ_FSM_MORE; ) {
		/*
		 * This is a good place to be paranoid about the various
		 * pointers still pointing to the things we expect.
		 */
		CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
		CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC);
		CHECK_OBJ_NOTNULL(req, REQ_MAGIC);

		/*
		 * We don't want the thread workspace to be used for
		 * anything of long duration, so mandate that it be
		 * empty on state-transitions.
		 */
		WS_Assert(wrk->aws);
		assert(wrk->aws->s == wrk->aws->f);

		switch (req->req_step) {
#define REQ_STEP(l,u,arg) \
		    case R_STP_##u: \
			if (DO_DEBUG(DBG_REQ_STATE)) \
				cnt_diag(req, #u); \
			nxt = cnt_##l arg; \
			break;
#include "tbl/steps.h"
#undef REQ_STEP
		default:
			WRONG("State engine misfire");
		}
		WS_Assert(wrk->aws);
		CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC);
	}
	wrk->vsl = NULL;
	if (nxt == REQ_FSM_DONE) {
		AN(req->vsl->wid);
		VRB_Free(req);
		req->wrk = NULL;
	}
	return (nxt);
}
Example #9
0
static struct http *
vrt_selecthttp(const struct vrt_ctx *ctx, enum gethdr_e where)
{
	struct http *hp;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	switch (where) {
	case HDR_REQ:
		hp = ctx->http_req;
		break;
	case HDR_BEREQ:
		hp = ctx->http_bereq;
		break;
	case HDR_BERESP:
		hp = ctx->http_beresp;
		break;
	case HDR_RESP:
		hp = ctx->http_resp;
		break;
	case HDR_OBJ:
		hp = ctx->http_obj;
		break;
	default:
		WRONG("vrt_selecthttp 'where' invalid");
	}
	return (hp);
}
Example #10
0
static void
vex_print_rhs(const struct vex_rhs *rhs)
{

	CHECK_OBJ_NOTNULL(rhs, VEX_RHS_MAGIC);
	fprintf(stderr, "rhs=");
	switch (rhs->type) {
	case VEX_INT:
		fprintf(stderr, "INT(%jd)", (intmax_t)rhs->val_int);
		break;
	case VEX_FLOAT:
		fprintf(stderr, "FLOAT(%f)", rhs->val_float);
		break;
	case VEX_STRING:
		AN(rhs->val_string);
		fprintf(stderr, "STRING(%s)", rhs->val_string);
		break;
	case VEX_REGEX:
		AN(rhs->val_string);
		AN(rhs->val_regex);
		fprintf(stderr, "REGEX(%s)", rhs->val_string);
		break;
	default:
		WRONG("rhs type");
		break;
	}
}
Example #11
0
static void
vbf_fetch_thread(struct worker *wrk, void *priv)
{
	struct busyobj *bo;
	enum fetch_step stp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);

	THR_SetBusyobj(bo);
	stp = F_STP_MKBEREQ;

	while (stp != F_STP_DONE) {
		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
		bo->step = stp;
		switch(stp) {
#define FETCH_STEP(l, U, arg)						\
		case F_STP_##U:						\
			stp = vbf_stp_##l arg;				\
			break;
#include "tbl/steps.h"
#undef FETCH_STEP
		default:
			WRONG("Illegal fetch_step");
		}
		if (stp != F_STP_DONE)
			VSLb(bo->vsl, SLT_Debug, "%s -> %s",
			    vbf_step_name(bo->step), vbf_step_name(stp));
	}
	assert(WRW_IsReleased(wrk));
	THR_SetBusyobj(NULL);
}
static void
v1d_WriteDirObj(struct req *req)
{
	enum objiter_status ois;
	ssize_t len;
	struct objiter *oi;
	void *ptr;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);

	oi = ObjIterBegin(req->wrk, req->obj);
	XXXAN(oi);

	do {
		ois = ObjIter(oi, &ptr, &len);
		switch(ois) {
		case OIS_DONE:
			AZ(len);
			break;
		case OIS_ERROR:
			break;
		case OIS_DATA:
		case OIS_STREAM:
			if (VDP_bytes(req,
			     ois == OIS_DATA ? VDP_NULL : VDP_FLUSH,  ptr, len))
				ois = OIS_ERROR;
			break;
		default:
			WRONG("Wrong OIS value");
		}
	} while (ois == OIS_DATA || ois == OIS_STREAM);
	(void)VDP_bytes(req, VDP_FINISH,  NULL, 0);
	ObjIterEnd(&oi);
}
static int
cnt_miss(struct sess *sp)
{

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);

    AZ(sp->obj);
    AN(sp->objcore);
    AN(sp->objhead);
    WS_Reset(sp->wrk->ws, NULL);
    sp->wrk->bereq = &sp->wrk->http[0];
    http_Setup(sp->wrk->bereq, sp->wrk->ws);
    http_FilterHeader(sp, HTTPH_R_FETCH);
    VCL_miss_method(sp);
    switch(sp->handling) {
    case VCL_RET_ERROR:
        HSH_DerefObjCore(sp);
        sp->step = STP_ERROR;
        return (0);
    case VCL_RET_PASS:
        HSH_DerefObjCore(sp);
        sp->step = STP_PASS;
        return (0);
    case VCL_RET_FETCH:
        sp->step = STP_FETCH;
        return (0);
    case VCL_RET_RESTART:
        HSH_DerefObjCore(sp);
        INCOMPL();
    default:
        WRONG("Illegal action in vcl_miss{}");
    }
}
Example #14
0
SES_Proto_Sess(struct worker *wrk, void *arg)
{
	struct req *req;
	struct sess *sp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC);
	WS_Release(sp->ws, 0);

	/*
	 * Assume we're going to receive something that will likely
	 * involve a request...
	 */
	(void)VTCP_blocking(sp->fd);
	req = Req_New(wrk, sp);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	req->htc->fd = sp->fd;
	SES_RxInit(req->htc, req->ws,
	    cache_param->http_req_size, cache_param->http_req_hdr_len);

	if (sp->sess_step < S_STP_H1_LAST) {
		wrk->task.func = SES_Proto_Req;
		wrk->task.priv = req;
	} else if (sp->sess_step < S_STP_PROXY_LAST) {
		wrk->task.func = VPX_Proto_Sess;
		wrk->task.priv = req;
	} else {
		WRONG("Wrong session step");
	}
}
Example #15
0
void
SES_Delete(struct sess *sp, enum sess_close reason, double now)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);

	if (reason != SC_NULL)
		SES_Close(sp, reason);
	assert(sp->fd < 0);

	if (isnan(now))
		now = VTIM_real();
	AZ(isnan(sp->t_open));
	if (now < sp->t_open) {
		VSL(SLT_Debug, sp->vxid,
		    "Clock step (now=%f < t_open=%f)",
		    now, sp->t_open);
		if (now + cache_param->clock_step < sp->t_open)
			WRONG("Clock step detected");
		now = sp->t_open; /* Do not log negatives */
	}

	if (reason == SC_NULL)
		reason = (enum sess_close)-sp->fd;

	VSL(SLT_SessClose, sp->vxid, "%s %.3f",
	    sess_close_2str(reason, 0), now - sp->t_open);
	VSL(SLT_End, sp->vxid, "%s", "");
	SES_Rel(sp);
}
Example #16
0
struct http *
VRT_selecthttp(VRT_CTX, enum gethdr_e where)
{
	struct http *hp;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	switch (where) {
	case HDR_REQ:
		hp = ctx->http_req;
		break;
	case HDR_REQ_TOP:
		hp = ctx->http_req_top;
		break;
	case HDR_BEREQ:
		hp = ctx->http_bereq;
		break;
	case HDR_BERESP:
		hp = ctx->http_beresp;
		break;
	case HDR_RESP:
		hp = ctx->http_resp;
		break;
	default:
		WRONG("VRT_selecthttp 'where' invalid");
	}
	return (hp);
}
Example #17
0
void *run_thread(void* tdata) {
  mca_status_t status;
  mrapi_info_t version;

  mrapi_parameters_t parms = 0;
  mrapi_resource_t     *caches_root;
  mrapi_rsrc_filter_t   filter;
  mrapi_resource_t     *l3cache;
  size_t                attr_size;
  uint32_t              cache_hits;

  thread_data* t = (thread_data*)tdata;
  printf("run thread: t=%d TID: %s\n", t->tid,print_tid()); 

  mrapi_initialize(DOMAIN,NODE+t->tid,parms,&version,&status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }
 
  printf("t=%d mrapi_resources_get TID: %s\n",t->tid,print_tid()); 
  /* Get the caches in a resource tree */
  filter = MRAPI_RSRC_CACHE;
  caches_root = mrapi_resources_get(filter, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  /* Select the L3 cache */
  l3cache = caches_root->children[0];

  printf("t=%d mrapi_dynamic_attribute_start TID: %s\n",t->tid,print_tid());
  /* Start, reset, get, and then stop the attribute 'cache_hits' for the L3 cache */
  mrapi_dynamic_attribute_start(l3cache, 1, &l3cache_hits_rollover, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }


  printf("t=%d mrapi_dynamic_attribute_reset TID:%s\n",t->tid,print_tid());
  mrapi_dynamic_attribute_reset(l3cache, 1, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  printf("t=%d mrapi_get_attribute TID: %s\n",t->tid,print_tid());
  attr_size = 4;
  mrapi_resource_get_attribute(l3cache, 1, (void *)&cache_hits, attr_size, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  printf("t=%d mrapi_dynamic_attribute_stop TID: %s\n",t->tid,print_tid());
  mrapi_dynamic_attribute_stop(l3cache, 1, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  printf("t=%d mrapi_resource_tree_free TID: %s\n",t->tid,print_tid());
  /* Free the caches resource tree */
  mrapi_resource_tree_free(&caches_root, &status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  printf("t=%d mrapi_finalize TID:%s\n",t->tid,print_tid());
  mrapi_finalize(&status);
  if (status != MRAPI_SUCCESS) { WRONG(status) }

  printf("t=%d DONE TID: %s\n",t->tid,print_tid());
  return NULL;
}
void
CNT_Session(struct sess *sp)
{
    int done;
    struct worker *w;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    w = sp->wrk;
    CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);

    /*
     * Possible entrance states
     */
    assert(
        sp->step == STP_FIRST ||
        sp->step == STP_START ||
        sp->step == STP_LOOKUP ||
        sp->step == STP_RECV);

    /*
     * Whenever we come in from the acceptor we need to set blocking
     * mode, but there is no point in setting it when we come from
     * ESI or when a parked sessions returns.
     * It would be simpler to do this in the acceptor, but we'd rather
     * do the syscall in the worker thread.
     */
    if (sp->step == STP_FIRST || sp->step == STP_START)
        TCP_blocking(sp->fd);

    for (done = 0; !done; ) {
        assert(sp->wrk == w);
        /*
         * This is a good place to be paranoid about the various
         * pointers still pointing to the things we expect.
         */
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
        CHECK_OBJ_ORNULL(sp->obj, OBJECT_MAGIC);
        CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
        CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
        WS_Assert(w->ws);

        switch (sp->step) {
#define STEP(l,u) \
		    case STP_##u: \
			if (params->diag_bitmap & 0x01) \
				cnt_diag(sp, #u); \
			done = cnt_##l(sp); \
		        break;
#include "steps.h"
#undef STEP
        default:
            WRONG("State engine misfire");
        }
        WS_Assert(w->ws);
        CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
    }
    WSL_Flush(w, 0);
    AZ(w->wfd);
}
Example #19
0
static void
vbf_fetch_thread(struct worker *wrk, void *priv)
{
	struct busyobj *bo;
	enum fetch_step stp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(bo->fetch_objcore, OBJCORE_MAGIC);

	THR_SetBusyobj(bo);
	stp = F_STP_MKBEREQ;
	assert(bo->doclose == SC_NULL);
	assert(isnan(bo->t_first));
	assert(isnan(bo->t_prev));
	VSLb_ts_busyobj(bo, "Start", W_TIM_real(wrk));

	bo->wrk = wrk;
	wrk->vsl = bo->vsl;

	while (stp != F_STP_DONE) {
		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
		assert(bo->refcount >= 1);
		switch(stp) {
#define FETCH_STEP(l, U, arg)						\
		case F_STP_##U:						\
			stp = vbf_stp_##l arg;				\
			break;
#include "tbl/steps.h"
#undef FETCH_STEP
		default:
			WRONG("Illegal fetch_step");
		}
	}
	assert(WRW_IsReleased(wrk));

	assert(bo->director_state == DIR_S_NULL);

	http_Teardown(bo->bereq);
	http_Teardown(bo->beresp);

	if (bo->state == BOS_FINISHED) {
		AZ(bo->fetch_objcore->flags & OC_F_FAILED);
		HSH_Complete(bo->fetch_objcore);
		VSLb(bo->vsl, SLT_Length, "%ju",
		    (uintmax_t)ObjGetLen(bo->wrk, bo->fetch_objcore));
	}
	AZ(bo->fetch_objcore->busyobj);

	if (bo->ims_oc != NULL)
		(void)HSH_DerefObjCore(wrk, &bo->ims_oc);


	wrk->vsl = NULL;
	VBO_DerefBusyObj(wrk, &bo);
	THR_SetBusyobj(NULL);
}
static int
cnt_recv(struct sess *sp)
{

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
    AZ(sp->obj);

    SES_ResetBackendTimeouts(sp);

    /* By default we use the first backend */
    AZ(sp->director);
    sp->director = sp->vcl->director[0];
    AN(sp->director);

    sp->disable_esi = 0;

    VCL_recv_method(sp);
    if (sp->restarts >= params->max_restarts) {
        if (sp->err_code == 0)
            sp->err_code = 503;
        sp->step = STP_ERROR;
        return (0);
    }

    if (!strcmp(sp->http->hd[HTTP_HDR_REQ].b, "HEAD")) {
        sp->wantbody = 0;
        http_ForceGet(sp->http);
    } else
        sp->wantbody = 1;

    sp->sendbody = 0;
    switch(sp->handling) {
    case VCL_RET_LOOKUP:
        /* XXX: discard req body, if any */
        sp->step = STP_LOOKUP;
        return (0);
    case VCL_RET_PIPE:
        if (sp->esis > 0) {
            /* XXX: VSL something */
            INCOMPL();
            /* sp->step = STP_DONE; */
            return (1);
        }
        sp->step = STP_PIPE;
        return (0);
    case VCL_RET_PASS:
        sp->step = STP_PASS;
        return (0);
    case VCL_RET_ERROR:
        /* XXX: discard req body, if any */
        sp->step = STP_ERROR;
        return (0);
    default:
        WRONG("Illegal action in vcl_recv{}");
    }
}
Example #21
0
static void
dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn,
     VCL_STRING addr, VCL_STRING port, VCL_PROBE probe)
{
	struct addrinfo hints, *res = NULL;
	struct suckaddr *sa;
	VCL_BACKEND dir, dir2;
	struct vrt_backend vrt;

	CHECK_OBJ_NOTNULL(dyn, VMOD_DEBUG_DYN_MAGIC);
	XXXAN(addr);
	XXXAN(port);

	INIT_OBJ(&vrt, VRT_BACKEND_MAGIC);
	vrt.port = port;
	vrt.vcl_name = dyn->vcl_name;
	vrt.hosthdr = addr;
	vrt.probe = probe;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	AZ(getaddrinfo(addr, port, &hints, &res));
	XXXAZ(res->ai_next);

	sa = VSA_Malloc(res->ai_addr, res->ai_addrlen);
	AN(sa);
	if (VSA_Get_Proto(sa) == AF_INET) {
		vrt.ipv4_addr = addr;
		vrt.ipv4_suckaddr = sa;
	} else if (VSA_Get_Proto(sa) == AF_INET6) {
		vrt.ipv6_addr = addr;
		vrt.ipv6_suckaddr = sa;
	} else
		WRONG("Wrong proto family");

	freeaddrinfo(res);

	dir = VRT_new_backend(ctx, &vrt);
	AN(dir);

	/*
	 * NB: A real dynamic backend should not replace the previous
	 * instance if the new one is identical.  We do it here because
	 * the d* tests requires a replacement.
	 */
	AZ(pthread_mutex_lock(&dyn->mtx));
	dir2 = dyn->dir;
	dyn->dir = dir;
	AZ(pthread_mutex_unlock(&dyn->mtx));

	if (dir2 != NULL)
		VRT_delete_backend(ctx, &dir2);

	free(sa);
}
Example #22
0
int
vtc_send_proxy(int fd, int version, const struct suckaddr *sac,
    const struct suckaddr *sas)
{
	struct vsb *vsb;
	char hc[VTCP_ADDRBUFSIZE];
	char pc[VTCP_PORTBUFSIZE];
	char hs[VTCP_ADDRBUFSIZE];
	char ps[VTCP_PORTBUFSIZE];
	int i, len;
	int proto;

	AN(sac);
	AN(sas);

	assert(version == 1 || version == 2);
	vsb = VSB_new_auto();
	AN(vsb);

	proto = VSA_Get_Proto(sas);
	assert(proto == PF_INET6 || proto == PF_INET);

	if (version == 1) {
		VSB_bcat(vsb, vpx1_sig, sizeof(vpx1_sig));
		if (proto == PF_INET6)
			VSB_printf(vsb, " TCP6 ");
		else if (proto == PF_INET)
			VSB_printf(vsb, " TCP4 ");
		VTCP_name(sac, hc, sizeof(hc), pc, sizeof(pc));
		VTCP_name(sas, hs, sizeof(hs), ps, sizeof(ps));
		VSB_printf(vsb, "%s %s %s %s\r\n", hc, hs, pc, ps);
	} else if (version == 2) {
		VSB_bcat(vsb, vpx2_sig, sizeof(vpx2_sig));
		VSB_putc(vsb, 0x21);
		if (proto == PF_INET6) {
			VSB_putc(vsb, 0x21);
			VSB_putc(vsb, 0x00);
			VSB_putc(vsb, 0x24);
		} else if (proto == PF_INET) {
			VSB_putc(vsb, 0x11);
			VSB_putc(vsb, 0x00);
			VSB_putc(vsb, 0x0c);
		}
		vpx_enc_addr(vsb, proto, sac);
		vpx_enc_addr(vsb, proto, sas);
		vpx_enc_port(vsb, sac);
		vpx_enc_port(vsb, sas);
	} else
		WRONG("Wrong proxy version");

	AZ(VSB_finish(vsb));
	len = VSB_len(vsb);
	i = write(fd, VSB_data(vsb), len);
	VSB_delete(vsb);
	return (i != len);
}
Example #23
0
static int
cnt_miss(struct worker *wrk, struct req *req)
{
	struct busyobj *bo;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
	bo = req->busyobj;
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	AZ(req->obj);

	HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq);
	http_FilterReq(req, HTTPH_R_FETCH);
	http_ForceGet(bo->bereq);
	if (cache_param->http_gzip_support) {
		/*
		 * We always ask the backend for gzip, even if the
		 * client doesn't grok it.  We will uncompress for
		 * the minority of clients which don't.
		 */
		http_Unset(bo->bereq, H_Accept_Encoding);
		http_SetHeader(bo->bereq, "Accept-Encoding: gzip");
	}

	VCL_miss_method(req);

	if (req->handling == VCL_RET_FETCH) {
		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
		req->req_step = R_STP_FETCH;
		return (0);
	}

	AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
	req->objcore = NULL;
	http_Teardown(bo->bereq);
	VBO_DerefBusyObj(wrk, &req->busyobj);

	switch(req->handling) {
	case VCL_RET_ERROR:
		req->req_step = R_STP_ERROR;
		break;
	case VCL_RET_PASS:
		req->req_step = R_STP_PASS;
		break;
	case VCL_RET_RESTART:
		req->req_step = R_STP_RESTART;
		break;
	default:
		WRONG("Illegal action in vcl_miss{}");
	}
	return (0);
}
Example #24
0
static int
http1_dissect(struct worker *wrk, struct req *req)
{

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->transport, TRANSPORT_MAGIC);

	/* Allocate a new vxid now that we know we'll need it. */
	AZ(req->vsl->wid);
	req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);

	VSLb(req->vsl, SLT_Begin, "req %u rxreq", VXID(req->sp->vxid));
	VSL(SLT_Link, req->sp->vxid, "req %u rxreq", VXID(req->vsl->wid));
	AZ(isnan(req->t_first)); /* First byte timestamp set by http1_wait */
	AZ(isnan(req->t_req));	 /* Complete req rcvd set by http1_wait */
	req->t_prev = req->t_first;
	VSLb_ts_req(req, "Start", req->t_first);
	VSLb_ts_req(req, "Req", req->t_req);

	HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
	req->err_code = HTTP1_DissectRequest(req->htc, req->http);

	/* If we could not even parse the request, just close */
	if (req->err_code != 0) {
		VSLb(req->vsl, SLT_HttpGarbage, "%.*s",
		    (int)(req->htc->rxbuf_e - req->htc->rxbuf_b),
		    req->htc->rxbuf_b);
		wrk->stats->client_req_400++;
		req->doclose = SC_RX_JUNK;
		http1_abort(req, 400);
		return (-1);
	}

	assert (req->req_body_status == REQ_BODY_INIT);

	switch (req->htc->body_status) {
	case BS_CHUNKED:
		req->req_body_status = REQ_BODY_WITHOUT_LEN;
		break;
	case BS_LENGTH:
		req->req_body_status = REQ_BODY_WITH_LEN;
		break;
	case BS_NONE:
		req->req_body_status = REQ_BODY_NONE;
		break;
	case BS_EOF:
		req->req_body_status = REQ_BODY_WITHOUT_LEN;
		break;
	default:
		WRONG("Unknown req_body_status situation");
	}
	return (0);
}
Example #25
0
main()
{
int i,offset;

   offset = 5;
   for (i = START;i <= STOP;i++) {
      printf("The square of %3d is %4d, and its cube is %6d\n",
              i+offset,SQUR(i+offset),CUBE(i+offset));
      printf("The wrong of  %3d is %6d\n",i+offset,WRONG(i+offset));
   }
}
Example #26
0
static void
vbf_fetch_thread(struct worker *wrk, void *priv)
{
	struct busyobj *bo;
	enum fetch_step stp;
	double t_hdr, t_body;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);

	THR_SetBusyobj(bo);
	stp = F_STP_MKBEREQ;
	bo->t_start = VTIM_real();
	bo->t_send = NAN;
	bo->t_sent = NAN;
	bo->t_hdr = NAN;
	bo->t_body = NAN;

	while (stp != F_STP_DONE) {
		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
		bo->step = stp;
		switch(stp) {
#define FETCH_STEP(l, U, arg)						\
		case F_STP_##U:						\
			stp = vbf_stp_##l arg;				\
			break;
#include "tbl/steps.h"
#undef FETCH_STEP
		default:
			WRONG("Illegal fetch_step");
		}
		VSLb(bo->vsl, SLT_Debug, "%s -> %s",
		    vbf_step_name(bo->step), vbf_step_name(stp));
	}
	assert(WRW_IsReleased(wrk));

	if (bo->state == BOS_FAILED)
		assert(bo->fetch_objcore->flags & OC_F_FAILED);

	if (bo->ims_obj != NULL)
		(void)HSH_DerefObj(&wrk->stats, &bo->ims_obj);

	t_hdr = bo->t_hdr - bo->t_sent;
	t_body = bo->t_body - bo->t_hdr;
	VSLb(bo->vsl, SLT_BereqEnd, "%.9f %.9f %.9f %.9f %.9f %.9f",
	     bo->t_start,
	     VTIM_real(),
	     bo->t_sent - bo->t_send,
	     t_hdr, t_body, t_hdr + t_body);

	VBO_DerefBusyObj(wrk, &bo);
	THR_SetBusyobj(NULL);
}
Example #27
0
ses_handle(struct waited *wp, enum wait_event ev, double now)
{
	struct sess *sp;
	struct pool *pp;
	struct pool_task *tp;
	const struct transport *xp;

	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
	CAST_OBJ_NOTNULL(sp, wp->priv1, SESS_MAGIC);
	CAST_OBJ_NOTNULL(xp, (const void*)wp->priv2, TRANSPORT_MAGIC);
	AN(wp->priv2);
	assert((void *)sp->ws->f == wp);
	wp->magic = 0;
	wp = NULL;

	WS_Release(sp->ws, 0);

	switch (ev) {
	case WAITER_TIMEOUT:
		SES_Delete(sp, SC_RX_TIMEOUT, now);
		break;
	case WAITER_REMCLOSE:
		SES_Delete(sp, SC_REM_CLOSE, now);
		break;
	case WAITER_ACTION:
		pp = sp->pool;
		CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
		assert(sizeof *tp <= WS_Reserve(sp->ws, sizeof *tp));
		tp = (void*)sp->ws->f;
		tp->func = xp->unwait;
		tp->priv = sp;
		if (Pool_Task(pp, tp, TASK_QUEUE_REQ))
			SES_Delete(sp, SC_OVERLOAD, now);
		break;
	case WAITER_CLOSE:
		WRONG("Should not see WAITER_CLOSE on client side");
		break;
	default:
		WRONG("Wrong event in ses_handle");
	}
}
Example #28
0
static FILE *
getdst(enum ocx_chan chan)
{
	if (chan == OCX_DIAG)
		return (stderr);
	if (chan == OCX_TRACE)
		return (tracefile);
	if (chan == OCX_DEBUG)
		return (stdout);
	WRONG("Wrong ocx_chan");
	NEEDLESS_RETURN(NULL);
}
static struct ws *wsfind(VRT_CTX, VCL_ENUM which) {
    if (!strcmp(which, "client")) {
        return ctx->ws;
    } else if (!strcmp(which, "backend")) {
        return ctx->bo->ws;
    } else if (!strcmp(which, "session")) {
        return ctx->req->sp->ws;
    } else if (!strcmp(which, "thread")) {
        return ctx->req->wrk->aws;
    } else
        WRONG("No such workspace.");
}
Example #30
0
const char *
HTC_Status(enum htc_status_e e)
{
	switch (e) {
#define HTC_STATUS(e, n, s, l)				\
		case HTC_S_ ## e:	return (s);
#include "tbl/htc.h"
	default:
		WRONG("HTC_Status");
	}
	NEEDLESS(return (NULL));
}