Commit 70667082 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Introduce session attributes which we store as a 16 bit index into

the session workspace to compress struct sess.
parent 9a96a8fd
......@@ -119,6 +119,7 @@ struct poolparam;
struct req;
struct sess;
struct sesspool;
struct suckaddr;
struct vbc;
struct vrt_backend;
struct vrt_priv;
......@@ -643,6 +644,14 @@ struct req {
* works, is not realistic without a lot of code changes.
*/
enum sess_attr {
#define SESS_ATTR(UP, low, typ, len) SA_##UP,
#include "tbl/sess_attr.h"
#undef SESS_ATTR
SA_LAST
};
struct sess {
unsigned magic;
#define SESS_MAGIC 0x2c2f9c5a
......@@ -663,15 +672,7 @@ struct sess {
struct ws ws[1];
/*
* This gets quite involved, but we don't want to waste space
* on up to 4 pointers of 8 bytes in struct sess.
*/
char *addrs;
#define sess_remote_addr(sp) \
((struct suckaddr *)(void*)((sp)->addrs))
#define sess_local_addr(sp) \
((struct suckaddr *)(void*)((sp)->addrs + vsa_suckaddr_len))
uint16_t sattr[SA_LAST];
/* formatted ascii client address */
char *client_addr_str;
......@@ -1002,6 +1003,12 @@ struct req *SES_GetReq(const struct worker *, struct sess *);
void SES_ReleaseReq(struct req *);
void SES_sess_pool_task(struct worker *wrk, void *arg);
#define SESS_ATTR(UP, low, typ, len) \
int SES_Get_##low(const struct sess *sp, typ *dst); \
void SES_Reserve_##low(struct sess *sp, typ *dst);
#include "tbl/sess_attr.h"
#undef SESS_ATTR
/* cache_shmlog.c */
extern struct VSC_C_main *VSC_C_main;
void VSM_Init(void);
......
......@@ -291,9 +291,9 @@ vca_make_session(struct worker *wrk, void *arg)
{
struct sesspool *pp;
struct sess *sp;
const char *lsockname;
struct wrk_accept *wa;
struct sockaddr_storage ss;
struct suckaddr *sa;
socklen_t sl;
char laddr[VTCP_ADDRBUFSIZE];
char lport[VTCP_PORTBUFSIZE];
......@@ -326,39 +326,44 @@ vca_make_session(struct worker *wrk, void *arg)
sp->fd = wa->acceptsock;
wa->acceptsock = -1;
lsockname = wa->acceptlsock->name;
AN(lsockname);
assert(wa->acceptaddrlen <= vsa_suckaddr_len);
AN(VSA_Build(sess_remote_addr(sp), &wa->acceptaddr, wa->acceptaddrlen));
vca_pace_good();
wrk->stats->sess_conn++;
WS_Release(wrk->aws, 0);
if (need_test) {
vca_tcp_opt_test(sp->fd);
need_test = 0;
}
vca_tcp_opt_set(sp->fd, 0);
AN(sp->addrs);
sl = sizeof ss;
AZ(getsockname(sp->fd, (void*)&ss, &sl));
AN(VSA_Build(sess_local_addr(sp), &ss, sl));
assert(VSA_Sane(sess_local_addr(sp)));
assert(wa->acceptaddrlen <= vsa_suckaddr_len);
SES_Reserve_remote_addr(sp, &sa);
AN(VSA_Build(sa, &wa->acceptaddr, wa->acceptaddrlen));
SES_Reserve_client_addr(sp, &sa);
AN(VSA_Build(sa, &wa->acceptaddr, wa->acceptaddrlen));
VTCP_name(sess_remote_addr(sp), laddr, sizeof laddr,
lport, sizeof lport);
VTCP_name(sa, laddr, sizeof laddr, lport, sizeof lport);
sp->client_addr_str = WS_Copy(sp->ws, laddr, -1);
AN(sp->client_addr_str);
sp->client_port_str = WS_Copy(sp->ws, lport, -1);
AN(sp->client_port_str);
VTCP_name(sess_local_addr(sp), laddr, sizeof laddr,
lport, sizeof lport);
sl = sizeof ss;
AZ(getsockname(sp->fd, (void*)&ss, &sl));
SES_Reserve_local_addr(sp, &sa);
AN(VSA_Build(sa, &ss, sl));
SES_Reserve_server_addr(sp, &sa);
AN(VSA_Build(sa, &ss, sl));
VTCP_name(sa, laddr, sizeof laddr, lport, sizeof lport);
VSL(SLT_Begin, sp->vxid, "sess 0 HTTP/1");
VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f %d",
sp->client_addr_str, sp->client_port_str, lsockname, laddr, lport,
sp->client_addr_str, sp->client_port_str,
wa->acceptlsock->name, laddr, lport,
sp->t_open, sp->fd);
WS_Release(wrk->aws, 0);
vca_pace_good();
wrk->stats->sess_conn++;
if (need_test) {
vca_tcp_opt_test(sp->fd);
need_test = 0;
}
vca_tcp_opt_set(sp->fd, 0);
/* SES_sess_pool_task() must be sceduled with reserved WS */
assert(8 == WS_Reserve(sp->ws, 8));
wrk->task.func = SES_sess_pool_task;
......
......@@ -61,6 +61,58 @@ struct sesspool {
struct waiter *http1_waiter;
};
/*--------------------------------------------------------------------*/
static int
ses_get_attr(const struct sess *sp, enum sess_attr a, void **dst)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(a < SA_LAST);
AN(dst);
if (sp->sattr[a] == 0xffff) {
*dst = NULL;
return (-1);
} else {
*dst = sp->ws->s + sp->sattr[a];
return (0);
}
}
static void
ses_reserve_attr(struct sess *sp, enum sess_attr a, void **dst, int sz)
{
ssize_t o;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(a < SA_LAST);
assert(sz >= 0);
AN(dst);
o = WS_Reserve(sp->ws, sz);
assert(o >= sz);
*dst = sp->ws->f;
o = sp->ws->f - sp->ws->s;
WS_Release(sp->ws, sz);
assert(o >= 0 && o <= 0xffff);
sp->sattr[a] = (uint16_t)o;
}
#define SESS_ATTR(UP, low, typ, len) \
int \
SES_Get_##low(const struct sess *sp, typ *dst) \
{ \
return (ses_get_attr(sp, SA_##UP, (void**)dst)); \
} \
\
void \
SES_Reserve_##low(struct sess *sp, typ *dst) \
{ \
ses_reserve_attr(sp, SA_##UP, (void*)dst, len); \
}
#include "tbl/sess_attr.h"
#undef SESS_ATTR
/*--------------------------------------------------------------------
* Get a new session, preferably by recycling an already ready one
*
......@@ -80,14 +132,13 @@ SES_New(struct sesspool *pp)
sp = MPL_Get(pp->mpl_sess, &sz);
sp->magic = SESS_MAGIC;
sp->sesspool = pp;
memset(sp->sattr, 0xff, sizeof sp->sattr);
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 = WS_Alloc(sp->ws, vsa_suckaddr_len * 2);
AN(sp->addrs);
sp->t_open = NAN;
sp->t_idle = NAN;
......@@ -444,6 +495,6 @@ SES_DeletePool(struct sesspool *pp)
MPL_Destroy(&pp->mpl_sess);
MPL_Destroy(&pp->mpl_req);
/* Delete session pool must stop acceptor threads */
INCOMPL();
FREE_OBJ(pp);
INCOMPL();
}
......@@ -37,7 +37,6 @@
#include "cache_director.h"
#include "vrt.h"
#include "vrt_obj.h"
#include "vsa.h"
static char vrt_hostname[255] = "";
......@@ -598,21 +597,25 @@ VRT_r_req_##field(VRT_CTX) \
VCL_IP
VRT_r_client_ip(VRT_CTX)
{
struct suckaddr *sa;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
return (sess_remote_addr(ctx->req->sp));
AZ(SES_Get_remote_addr(ctx->req->sp, &sa));
return (sa);
}
VCL_IP
VRT_r_server_ip(VRT_CTX)
{
struct suckaddr *sa;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
return (sess_local_addr(ctx->req->sp));
AZ(SES_Get_local_addr(ctx->req->sp, &sa));
return (sa);
}
const char*
......
......@@ -16,6 +16,7 @@ nobase_pkginclude_HEADERS = \
tbl/obj_attr.h \
tbl/req_body.h \
tbl/req_flags.h \
tbl/sess_attr.h \
tbl/sess_close.h \
tbl/steps.h \
tbl/symbol_kind.h \
......
/*-
* Copyright (c) 2015 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Session attributes should be stored as cheaply as possible in terms of
* memory. This stuff implements "small pointers", 16 bit offsets into
* the session workspace, for these bits.
*/
/*lint -save -e525 -e539 */
// upper lower type len
SESS_ATTR(REMOTE_ADDR, remote_addr, struct suckaddr *, vsa_suckaddr_len)
SESS_ATTR(LOCAL_ADDR, local_addr, struct suckaddr *, vsa_suckaddr_len)
SESS_ATTR(CLIENT_ADDR, client_addr, struct suckaddr *, vsa_suckaddr_len)
SESS_ATTR(SERVER_ADDR, server_addr, struct suckaddr *, vsa_suckaddr_len)
/*lint -restore */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment