static struct sess * ses_new(struct sesspool *pp) { struct sess *sp; unsigned sz; char *p, *e; CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC); sp = MPL_Get(pp->mpl_sess, &sz); sp->magic = SESS_MAGIC; sp->sesspool = pp; e = (char*)sp + sz; p = (char*)(sp + 1); p = (void*)PRNDUP(p); assert(p < e); WS_Init(sp->ws, "ses", p, e - p); sp->addrs = (void*)WS_Alloc(sp->ws, vsa_suckaddr_len * 2); sp->t_open = NAN; sp->t_idle = NAN; Lck_New(&sp->mtx, lck_sess); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); return (sp); }
void http_CopyHome(struct worker *w, int fd, const struct http *hp) { unsigned u, l; char *p; for (u = 0; u < hp->nhd; u++) { if (hp->hd[u].b == NULL) continue; if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e) { WSLH(w, fd, hp, u); continue; } l = Tlen(hp->hd[u]); p = WS_Alloc(hp->ws, l + 1); if (p != NULL) { WSLH(w, fd, hp, u); memcpy(p, hp->hd[u].b, l + 1L); hp->hd[u].b = p; hp->hd[u].e = p + l; } else { /* XXX This leaves a slot empty */ VSC_C_main->losthdr++; WSLR(w, SLT_LostHeader, fd, hp->hd[u]); hp->hd[u].b = NULL; hp->hd[u].e = NULL; } } }
void WRW_Reserve(struct worker *wrk, int *fd, struct vsl_log *vsl, double t0) { struct wrw *wrw; unsigned u; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(wrk->wrw); wrw = (void*)WS_Alloc(wrk->aws, sizeof *wrw); AN(wrw); memset(wrw, 0, sizeof *wrw); wrw->magic = WRW_MAGIC; u = WS_Reserve(wrk->aws, 0); u = PRNDDN(u); u /= sizeof(struct iovec); if (u > IOV_MAX) u = IOV_MAX; AN(u); wrw->iov = (void*)PRNDUP(wrk->aws->f); wrw->siov = u; wrw->ciov = u; wrw->werr = 0; wrw->liov = 0; wrw->niov = 0; wrw->wfd = fd; wrw->t0 = t0; wrw->vsl = vsl; wrk->wrw = wrw; }
unsigned HTTP1_Write(const struct worker *w, const struct http *hp, int resp) { unsigned u, l; if (resp) { l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " "); hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(hp->ws, 4); AN(hp->hd[HTTP_HDR_STATUS].b); assert(hp->status >= 100 && hp->status <= 999); sprintf(hp->hd[HTTP_HDR_STATUS].b, "%3d", hp->status); hp->hd[HTTP_HDR_STATUS].e = hp->hd[HTTP_HDR_STATUS].b + 3; l += WRW_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " "); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n"); } else { AN(hp->hd[HTTP_HDR_URL].b); l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " "); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " "); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n"); } for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { if (hp->hd[u].b == NULL) continue; AN(hp->hd[u].b); AN(hp->hd[u].e); l += WRW_WriteH(w, &hp->hd[u], "\r\n"); } l += WRW_Write(w, "\r\n", -1); return (l); }
char * VRT_IP_string(const struct sess *sp, const struct sockaddr_storage *sa) { char *p; const struct sockaddr_in *si4; const struct sockaddr_in6 *si6; const void *addr; int len; switch (sa->ss_family) { case AF_INET: len = INET_ADDRSTRLEN; si4 = (const void *)sa; addr = &(si4->sin_addr); break; case AF_INET6: len = INET6_ADDRSTRLEN; si6 = (const void *)sa; addr = &(si6->sin6_addr); break; default: INCOMPL(); } XXXAN(len); AN(p = WS_Alloc(sp->http->ws, len)); AN(inet_ntop(sa->ss_family, addr, p, len)); return (p); }
char * VRT_IP_string(const struct vrt_ctx *ctx, const struct sockaddr_storage *sa) { char *p; const struct sockaddr_in *si4; const struct sockaddr_in6 *si6; const void *addr; int len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); switch (sa->ss_family) { case AF_INET: len = INET_ADDRSTRLEN; si4 = (const void *)sa; addr = &(si4->sin_addr); break; case AF_INET6: len = INET6_ADDRSTRLEN; si6 = (const void *)sa; addr = &(si6->sin6_addr); break; default: INCOMPL(); } XXXAN(len); AN(p = WS_Alloc(ctx->ws, len)); AN(inet_ntop(sa->ss_family, addr, p, len)); return (p); }
static void answer_appropriate(struct vmod_fsdirector_file_system *fs) { unsigned available; char *url; char *url_start; char *url_end; size_t url_len; size_t root_len; char *path; struct stat stat_buf; if (strncmp("GET ", fs->htc.ws->s, 4)) { prepare_answer(&fs->htc, 405); prepare_body(&fs->htc); return; } url_start = &fs->htc.ws->s[4]; url_end = strchr(url_start, ' '); url_len = (url_end - url_start) + strlen(fs->root) + 1; url = WS_Alloc(fs->htc.ws, url_len); snprintf(url, url_len, "%s%s", fs->root, url_start); path = url; if (lstat(path, &stat_buf) < 0) { handle_file_error(&fs->htc, errno); return; } answer_file(fs, &stat_buf, path); }
struct vep_state * VEP_Init(struct vfp_ctx *vc, const struct http *req, vep_callback_t *cb, void *cb_priv) { struct vep_state *vep; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(req, HTTP_MAGIC); vep = WS_Alloc(vc->http->ws, sizeof *vep); AN(vep); INIT_OBJ(vep, VEP_MAGIC); vep->url = req->hd[HTTP_HDR_URL].b; vep->vc = vc; vep->vsb = VSB_new_auto(); AN(vep->vsb); if (cb != NULL) { vep->dogzip = 1; /* XXX */ VSB_printf(vep->vsb, "%c", VEC_GZ); vep->cb = cb; vep->cb_priv = cb_priv; } else { vep->cb = vep_default_cb; vep->cb_priv = &vep->cb_x; } vep->state = VEP_START; vep->crc = crc32(0L, Z_NULL, 0); vep->crcp = crc32(0L, Z_NULL, 0); vep->startup = 1; return (vep); }
VCL_STRING vmod_lf(const struct vrt_ctx *ctx){ char *p; p = WS_Alloc(ctx->ws,2); strcpy(p,"\n"); return p; }
VCL_IP vmod_ip(const struct vrt_ctx *ctx, VCL_STRING s, VCL_IP d) { struct addrinfo hints, *res0 = NULL; const struct addrinfo *res; int error; char *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(d); assert(VSA_Sane(d)); if (s != NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(s, "80", &hints, &res0); if (!error) { for (res = res0; res != NULL; res = res->ai_next) { if (VSA_Sane(res->ai_addr) && res->ai_addrlen >= VSA_Len(res->ai_addr)) { d = res->ai_addr; break; } } } } AN(d); p = WS_Alloc(ctx->ws, VSA_Len(d)); AN(p); memcpy(p, d, VSA_Len(d)); if (res0 != NULL) freeaddrinfo(res0); return (p); }
char * VRT_time_string(const struct sess *sp, double t) { char *p; AN(p = WS_Alloc(sp->http->ws, VTIM_FORMAT_SIZE)); VTIM_format(t, p); return (p); }
char * VRT_TIME_string(VRT_CTX, double t) { char *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); p = WS_Alloc(ctx->ws, VTIM_FORMAT_SIZE); if (p != NULL) VTIM_format(t, p); return (p); }
char * VRT_double_string(const struct sess *sp, double num) { char *p; int size; size = snprintf(NULL, 0, "%.3f", num) + 1; AN(p = WS_Alloc(sp->http->ws, size)); assert(snprintf(p, size, "%.3f", num) < size); return (p); }
char * VRT_int_string(const struct sess *sp, int num) { char *p; int size; size = snprintf(NULL, 0, "%d", num) + 1; AN(p = WS_Alloc(sp->req->http->ws, size)); assert(snprintf(p, size, "%d", num) < size); return (p); }
char * VRT_REAL_string(const struct vrt_ctx *ctx, double num) { char *p; int size; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); size = snprintf(NULL, 0, "%.3f", num) + 1; AN(p = WS_Alloc(ctx->ws, size)); assert(snprintf(p, size, "%.3f", num) < size); return (p); }
VCL_BLOB vmod_str2blob(const struct vrt_ctx *ctx, VCL_STRING s) { struct vmod_priv *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); p = (void*)WS_Alloc(ctx->ws, sizeof *p); AN(p); memset(p, 0, sizeof *p); p->len = strlen(s); p->priv = WS_Copy(ctx->ws, s, -1); return (p); }
void PIE_Init(struct sess *sp) { struct pipe *dp = (struct pipe *)sp->vc; struct vbe_conn *vc; CAST_OBJ_NOTNULL(vc, &(dp)->vc, VBE_CONN_MAGIC); CHECK_OBJ_NOTNULL(&((vc)->common), VBE_COMMON_MAGIC); assert((vc)->common.type == VBE_TYPE_PIPE); dp->magic = PIPE_MAGIC; dp->flags |= PIPE_F_STARTED; dp->sess = sp; dp->wrk = sp->wrk; dp->buf[0] = WS_Alloc(sp->ws, BUFSIZ); AN(dp->buf[0]); dp->buf[1] = WS_Alloc(sp->ws, BUFSIZ); AN(dp->buf[1]); dp->buflen[0] = 0; dp->buflen[1] = 0; dp->bufsize = BUFSIZ; dp->septum.type = SEPTUM_PIPE; dp->septum.arg = dp; }
char * WS_nDup(struct ws *ws, const char *s, size_t l) { char *p; WS_Assert(ws); p = WS_Alloc(ws, l + 1); if (p != NULL) { memcpy(p, s, l); p[l] = '\0'; } DSL(0x02, SLT_Debug, 0, "WS_nDup(%p, \"%s\", %zd) = %p", ws, s, p, l); WS_Assert(ws); return (p); }
char * WS_Dup(struct ws *ws, const char *s) { unsigned l; char *p; WS_Assert(ws); l = strlen(s) + 1; p = WS_Alloc(ws, l); if (p != NULL) memcpy(p, s, l); DSL(0x02, SLT_Debug, 0, "WS_Dup(%p, \"%s\") = %p", ws, s, p); WS_Assert(ws); return (p); }
void vmod_workspace_allocate(VRT_CTX, VCL_ENUM which, VCL_INT size) { struct ws *ws; char *s; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); AZ(ws->r); s = WS_Alloc(ws, size); if (!s) return; memset(s, '\0', size); }
static const char * truncate_querystring(struct ws *ws, const char *uri, const char *query_string) { int query_string_position; char *truncated_uri; query_string_position = query_string - uri; truncated_uri = WS_Alloc(ws, query_string_position); if (truncated_uri == NULL) { return uri; } memcpy(truncated_uri, uri, query_string_position); truncated_uri[query_string_position] = '\0'; return truncated_uri; }
VCL_STRING vmod_blob2hex(const struct vrt_ctx *ctx, VCL_BLOB b) { char *s, *p; uint8_t *q; int i; s = WS_Alloc(ctx->ws, b->len * 2 + 2); AN(s); p = s; q = b->priv; for (i = 0; i < b->len; i++) { sprintf(p, "%02x", *q); p += 2; q += 1; } VRT_priv_fini(b); return (s); }
static const char * vmod_hmac_sha256(const struct vrt_ctx *ctx, const char *key,size_t lkey, const char *msg,size_t lmsg,bool raw) { hashid hash = MHASH_SHA256; size_t blocksize = mhash_get_block_size(hash); char *p; char *ptmp; p = WS_Alloc(ctx->ws, blocksize * 2 + 1); ptmp = p; unsigned char *mac; unsigned u; u = WS_Reserve(ctx->ws, 0); assert(u > blocksize); mac = (unsigned char*)ctx->ws->f; int i; MHASH td; assert(msg); assert(key); assert(mhash_get_hash_pblock(hash) > 0); td = mhash_hmac_init(hash, (void *) key, lkey, mhash_get_hash_pblock(hash)); mhash(td, msg, lmsg); mhash_hmac_deinit(td,mac); if(raw){ WS_Release(ctx->ws, blocksize); return (char *)mac; } WS_Release(ctx->ws, 0); for (i = 0; i<blocksize;i++) { sprintf(ptmp,"%.2x",mac[i]); ptmp+=2; } return p; }
void V1L_Reserve(struct worker *wrk, struct ws *ws, int *fd, struct vsl_log *vsl, double t0) { struct v1l *v1l; unsigned u; void *res; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AZ(wrk->v1l); if (WS_Overflowed(ws)) return; res = WS_Snapshot(ws); v1l = WS_Alloc(ws, sizeof *v1l); if (v1l == NULL) return; INIT_OBJ(v1l, V1L_MAGIC); v1l->ws = ws; v1l->res = res; u = WS_Reserve(ws, 0); u = PRNDDN(u); u /= sizeof(struct iovec); if (u == 0) { WS_Release(ws, 0); WS_MarkOverflow(ws); return; } else if (u > IOV_MAX) u = IOV_MAX; v1l->iov = (void*)PRNDUP(ws->f); v1l->siov = u; v1l->ciov = u; v1l->werr = 0; v1l->liov = 0; v1l->niov = 0; v1l->wfd = fd; v1l->t0 = t0; v1l->vsl = vsl; wrk->v1l = v1l; }
VCL_IP vmod_ip(VRT_CTX, VCL_STRING s, VCL_IP d) { struct addrinfo hints, *res0 = NULL; const struct addrinfo *res; int error; void *p; struct suckaddr *r; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(d); assert(VSA_Sane(d)); p = WS_Alloc(ctx->ws, vsa_suckaddr_len); if (p == NULL) { VSLb(ctx->vsl, SLT_VCL_Error, "vmod std.ip(): insufficient workspace"); return d; } r = NULL; if (s != NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(s, "80", &hints, &res0); if (!error) { for (res = res0; res != NULL; res = res->ai_next) { r = VSA_Build(p, res->ai_addr, res->ai_addrlen); if (r != NULL) break; } } } if (r == NULL) { r = p; memcpy(r, d, vsa_suckaddr_len); } if (res0 != NULL) freeaddrinfo(res0); return (r); }
void VEP_Init(struct worker *wrk, vep_callback_t *cb) { struct vep_state *vep; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); AZ(wrk->busyobj->vep); vep = (void*)WS_Alloc(wrk->ws, sizeof *vep); AN(vep); memset(vep, 0, sizeof *vep); vep->magic = VEP_MAGIC; vep->wrk = wrk; vep->vsb = VSB_new_auto(); AN(vep->vsb); wrk->busyobj->vep = vep; if (cb != NULL) { vep->dogzip = 1; /* XXX */ VSB_printf(vep->vsb, "%c", VEC_GZ); vep->cb = cb; } else { vep->cb = vep_default_cb; } vep->state = VEP_START; vep->crc = crc32(0L, Z_NULL, 0); vep->crcp = crc32(0L, Z_NULL, 0); /* * We must force the GZIP header out as a SKIP string, otherwise * an object starting with <esi:include would have its GZIP header * appear after the included object (e000026.vtc) */ vep->startup = 1; vep->ver_p = ""; vep->last_mark = SKIP; vep_mark_common(vep, vep->ver_p, VERBATIM); vep->startup = 0; }
static const char * vmod_hash_sha256(const struct vrt_ctx *ctx, const char *msg) { MHASH td; hashid hash = MHASH_SHA256; unsigned char h[mhash_get_block_size(hash)]; int i; char *p; char *ptmp; td = mhash_init(hash); mhash(td, msg, strlen(msg)); mhash_deinit(td, h); p = WS_Alloc(ctx->ws,mhash_get_block_size(hash)*2 + 1); ptmp = p; for (i = 0; i<mhash_get_block_size(hash);i++) { sprintf(ptmp,"%.2x",h[i]); ptmp+=2; } return p; }
unsigned http_Write(struct worker *w, const struct http *hp, int resp) { unsigned u, l; int fd = *(w->wrw.wfd); if (resp) { l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " "); WSLH(w, fd, hp, HTTP_HDR_PROTO); hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(w->ws, 4); AN(hp->hd[HTTP_HDR_STATUS].b); sprintf(hp->hd[HTTP_HDR_STATUS].b, "%3d", hp->status); hp->hd[HTTP_HDR_STATUS].e = hp->hd[HTTP_HDR_STATUS].b + 3; l += WRW_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " "); WSLH(w, fd, hp, HTTP_HDR_STATUS); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n"); WSLH(w, fd, hp, HTTP_HDR_RESPONSE); } else { AN(hp->hd[HTTP_HDR_URL].b); l = WRW_WriteH(w, &hp->hd[HTTP_HDR_REQ], " "); WSLH(w, fd, hp, HTTP_HDR_REQ); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " "); WSLH(w, fd, hp, HTTP_HDR_URL); l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n"); WSLH(w, fd, hp, HTTP_HDR_PROTO); } for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { if (hp->hd[u].b == NULL) continue; AN(hp->hd[u].b); AN(hp->hd[u].e); l += WRW_WriteH(w, &hp->hd[u], "\r\n"); WSLH(w, fd, hp, u); } l += WRW_Write(w, "\r\n", -1); return (l); }
void VDP_push(struct req *req, vdp_bytes *func, void *priv, int bottom) { struct vdp_entry *vdp; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AN(func); vdp = WS_Alloc(req->ws, sizeof *vdp); AN(vdp); INIT_OBJ(vdp, VDP_ENTRY_MAGIC); vdp->func = func; vdp->priv = priv; if (bottom) VTAILQ_INSERT_TAIL(&req->vdp, vdp, list); else VTAILQ_INSERT_HEAD(&req->vdp, vdp, list); req->vdp_nxt = VTAILQ_FIRST(&req->vdp); AZ(vdp->func(req, VDP_INIT, &vdp->priv, NULL, 0)); }
static void http_PutField(const struct http *to, int field, const char *string) { char *p; unsigned l; CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); l = strlen(string); p = WS_Alloc(to->ws, l + 1); if (p == NULL) { VSLb(to->vsl, SLT_LostHeader, "%s", string); to->hd[field].b = NULL; to->hd[field].e = NULL; to->hdf[field] = 0; } else { memcpy(p, string, l + 1L); to->hd[field].b = p; to->hd[field].e = p + l; to->hdf[field] = 0; } }