Skip to content

Commit

Permalink
Adding support for item_size_max
Browse files Browse the repository at this point in the history
  • Loading branch information
bmatheny committed Jul 31, 2012
1 parent 480cc67 commit 93fd154
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 10 deletions.
11 changes: 11 additions & 0 deletions src/nc_conf.c
Expand Up @@ -61,6 +61,10 @@ static struct command conf_commands[] = {
conf_set_num,
offsetof(struct conf_pool, backlog) },

{ string("item_size_max"),
conf_set_num,
offsetof(struct conf_pool, item_size_max) },

{ string("client_connections"),
conf_set_num,
offsetof(struct conf_pool, client_connections) },
Expand Down Expand Up @@ -169,6 +173,7 @@ conf_pool_init(struct conf_pool *cp, struct string *name)
cp->distribution = CONF_UNSET_DIST;
cp->timeout = CONF_UNSET_NUM;
cp->backlog = CONF_UNSET_NUM;
cp->item_size_max = CONF_UNSET_NUM;

cp->client_connections = CONF_UNSET_NUM;

Expand Down Expand Up @@ -256,6 +261,7 @@ conf_pool_each_transform(void *elem, void *data)
sp->key_hash = hash_algos[cp->hash];
sp->timeout = cp->timeout;
sp->backlog = cp->backlog;
sp->item_size_max = (uint32_t)cp->item_size_max;

sp->client_connections = (uint32_t)cp->client_connections;

Expand Down Expand Up @@ -300,6 +306,7 @@ conf_dump(struct conf *cf)
log_debug(LOG_VVERB, " hash: %d", cp->hash);
log_debug(LOG_VVERB, " timeout: %d", cp->timeout);
log_debug(LOG_VVERB, " backlog: %d", cp->backlog);
log_debug(LOG_VVERB, " item_size_max: %d", cp->item_size_max);
log_debug(LOG_VVERB, " distribution: %d", cp->distribution);
log_debug(LOG_VVERB, " client_connections: %d",
cp->client_connections);
Expand Down Expand Up @@ -1186,6 +1193,10 @@ conf_validate_pool(struct conf *cf, struct conf_pool *cp)
cp->backlog = CONF_DEFAULT_LISTEN_BACKLOG;
}

if (cp->item_size_max == CONF_UNSET_NUM) {
cp->item_size_max = CONF_DEFAULT_ITEM_SIZE_MAX;
}

cp->client_connections = CONF_DEFAULT_CLIENT_CONNECTIONS;

if (cp->preconnect == CONF_UNSET_NUM) {
Expand Down
2 changes: 2 additions & 0 deletions src/nc_conf.h
Expand Up @@ -45,6 +45,7 @@
#define CONF_DEFAULT_DIST DIST_KETAMA
#define CONF_DEFAULT_TIMEOUT -1
#define CONF_DEFAULT_LISTEN_BACKLOG 512
#define CONF_DEFAULT_ITEM_SIZE_MAX 1048576 /* in bytes */
#define CONF_DEFAULT_CLIENT_CONNECTIONS 0
#define CONF_DEFAULT_PRECONNECT false
#define CONF_DEFAULT_AUTO_EJECT_HOSTS false
Expand Down Expand Up @@ -76,6 +77,7 @@ struct conf_pool {
dist_type_t distribution; /* distribution: */
int timeout; /* timeout: */
int backlog; /* backlog: */
int item_size_max; /* item_size_max: */
int client_connections; /* client_connections: */
int preconnect; /* preconnect: */
int auto_eject_hosts; /* auto_eject_hosts: */
Expand Down
1 change: 1 addition & 0 deletions src/nc_message.c
Expand Up @@ -224,6 +224,7 @@ _msg_get(void)
msg->key_start = NULL;
msg->key_end = NULL;
msg->vlen = 0;
msg->vlen_rem = 0;
msg->end = NULL;
msg->frag_id = 0;

Expand Down
1 change: 1 addition & 0 deletions src/nc_message.h
Expand Up @@ -75,6 +75,7 @@ struct msg {
uint8_t *key_start; /* key start */
uint8_t *key_end; /* key end */
uint32_t vlen; /* value length */
uint32_t vlen_rem; /* value length remaining for parse phase */
uint8_t *end; /* end marker */

uint64_t frag_id; /* id of fragmented message */
Expand Down
23 changes: 13 additions & 10 deletions src/nc_parse.c
Expand Up @@ -393,27 +393,29 @@ parse_request(struct msg *r)
}
/* vlen_start <- p */
r->token = p;
r->vlen = (uint32_t)(ch - '0');
r->vlen_rem = (uint32_t)(ch - '0');
state = SW_VLEN;
}

break;

case SW_VLEN:
if (ch >= '0' && ch <= '9') {
r->vlen = r->vlen * 10 + (uint32_t)(ch - '0');
r->vlen_rem = r->vlen_rem * 10 + (uint32_t)(ch - '0');
} else if (r->cas) {
if (ch != ' ') {
goto error;
}
/* vlen_end <- p - 1 */
p = p - 1; /* go back by 1 byte */
r->token = NULL;
r->vlen = r->vlen_rem;
state = SW_SPACES_BEFORE_CAS;
} else if (ch == ' ' || ch == CR) {
/* vlen_end <- p - 1 */
p = p - 1; /* go back by 1 byte */
r->token = NULL;
r->vlen = r->vlen_rem;
state = SW_RUNTO_CRLF;
} else {
goto error;
Expand Down Expand Up @@ -463,10 +465,10 @@ parse_request(struct msg *r)
break;

case SW_VAL:
m = p + r->vlen;
m = p + r->vlen_rem;
if (m >= b->last) {
ASSERT(r->vlen >= (uint32_t)(b->last - p));
r->vlen -= (uint32_t)(b->last - p);
ASSERT(r->vlen_rem >= (uint32_t)(b->last - p));
r->vlen_rem -= (uint32_t)(b->last - p);
m = b->last - 1;
p = m; /* move forward by vlen bytes */
break;
Expand Down Expand Up @@ -932,19 +934,20 @@ parse_response(struct msg *r)
}
/* vlen_start <- p */
r->token = p;
r->vlen = (uint32_t)(ch - '0');
r->vlen_rem = (uint32_t)(ch - '0');
state = SW_VLEN;
}

break;

case SW_VLEN:
if (ch >= '0' && ch <= '9') {
r->vlen = r->vlen * 10 + (uint32_t)(ch - '0');
r->vlen_rem = r->vlen_rem * 10 + (uint32_t)(ch - '0');
} else if (ch == ' ' || ch == CR) {
/* vlen_end <- p - 1 */
p = p - 1; /* go back by 1 byte */
r->token = NULL;
r->vlen = r->vlen_rem;
state = SW_RUNTO_CRLF;
} else {
goto error;
Expand All @@ -966,10 +969,10 @@ parse_response(struct msg *r)
break;

case SW_VAL:
m = p + r->vlen;
m = p + r->vlen_rem;
if (m >= b->last) {
ASSERT(r->vlen >= (uint32_t)(b->last - p));
r->vlen -= (uint32_t)(b->last - p);
ASSERT(r->vlen_rem >= (uint32_t)(b->last - p));
r->vlen_rem -= (uint32_t)(b->last - p);
m = b->last - 1;
p = m; /* move forward by vlen bytes */
break;
Expand Down
15 changes: 15 additions & 0 deletions src/nc_request.c
Expand Up @@ -357,6 +357,8 @@ req_recv_next(struct context *ctx, struct conn *conn, bool alloc)
static bool
req_filter(struct context *ctx, struct conn *conn, struct msg *msg)
{
struct server_pool *pool = conn->owner;

ASSERT(conn->client && !conn->proxy);

if (msg_empty(msg)) {
Expand All @@ -381,6 +383,19 @@ req_filter(struct context *ctx, struct conn *conn, struct msg *msg)
return true;
}

/* Handle excessively large request payloads */
if (msg->vlen > pool->item_size_max) {
ASSERT(conn->rmsg == NULL);
log_debug(LOG_ERR, "filter size %"PRIu32" > max %"PRIu32" req %"PRIu64" from c %d",
msg->vlen, pool->item_size_max, msg->id, conn->sd);
conn->done = 1;
req_put(msg);
return true;
} else {
log_debug(LOG_DEBUG, "filter size %"PRIu32" req %"PRIu64" from c %d",
msg->vlen, msg->id, conn->sd);
}

return false;
}

Expand Down
1 change: 1 addition & 0 deletions src/nc_server.h
Expand Up @@ -111,6 +111,7 @@ struct server_pool {
hash_t key_hash; /* key hasher */
int timeout; /* timeout in msec */
int backlog; /* listen backlog */
uint32_t item_size_max; /* maximum size object (bytes) */
uint32_t client_connections; /* maximum # client connection */
uint32_t server_connections; /* maximum # server connection */
int64_t server_retry_timeout; /* server retry timeout in usec */
Expand Down

0 comments on commit 93fd154

Please sign in to comment.