diff --git a/core/cache.c b/core/cache.c index 6d0a2364..423b07ec 100644 --- a/core/cache.c +++ b/core/cache.c @@ -295,7 +295,7 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint } } uci = &uwsgi.cache_items[index]; - if (expires) + if (expires && !(flags & UWSGI_CACHE_FLAG_ABSEXPIRE)) expires += uwsgi_now(); uci->expires = expires; uci->djbhash = djb33x_hash(key, keylen); @@ -333,7 +333,7 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint } else if (flags & UWSGI_CACHE_FLAG_UPDATE) { uci = &uwsgi.cache_items[index]; - if (expires) { + if (expires && !(flags & UWSGI_CACHE_FLAG_ABSEXPIRE)) { expires += uwsgi_now(); uci->expires = expires; } @@ -347,13 +347,14 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint struct uwsgi_header uh; uint8_t u_k[2]; uint8_t u_v[2]; + uint8_t u_e[2]; uint16_t vallen16 = vallen; - struct iovec iov[5]; + struct iovec iov[7]; struct msghdr mh; memset(&mh, 0, sizeof(struct msghdr)); mh.msg_iov = iov; - mh.msg_iovlen = 5; + mh.msg_iovlen = 7; u_k[0] = (uint8_t) (keylen & 0xff); u_k[1] = (uint8_t) ((keylen >> 8) & 0xff); @@ -376,9 +377,21 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint iov[4].iov_base = val; iov[4].iov_len = vallen16; + char es[sizeof(UMAX64_STR) + 1]; + uint16_t es_size = uwsgi_long2str2n(expires, es, sizeof(UMAX64_STR)); + + u_e[0] = (uint8_t) (es_size & 0xff); + u_e[1] = (uint8_t) ((es_size >> 8) & 0xff); + + iov[5].iov_base = u_e; + iov[5].iov_len = 2; + + iov[6].iov_base = es; + iov[6].iov_len = es_size; + uh.modifier1 = 111; uh.modifier2 = 10; - uh.pktsize = 2 + keylen + 2 + vallen16; + uh.pktsize = 2 + keylen + 2 + vallen16 + 2 + es_size; struct uwsgi_string_list *usl = uwsgi.cache_udp_node; while(usl) { diff --git a/core/master.c b/core/master.c index 97b2297f..586a1eb4 100644 --- a/core/master.c +++ b/core/master.c @@ -393,15 +393,22 @@ void *cache_udp_server_loop(void *noarg) { // cache set/update if (buf[3] == 10) { memcpy(&ss, buf + 4, 2); - if (ss > pktsize-4) continue; + if (4+ss > pktsize) continue; uint16_t keylen = ss; char *key = buf + 6; + if (keylen + 2 + 2 > pktsize) continue; memcpy(&ss, buf + 6 + keylen, 2); - if (ss > pktsize-(4+keylen)) continue; + if (4+keylen+ss > pktsize) continue; uint16_t vallen = ss; char *val = buf + 8 + keylen; + uint64_t expires = 0; + if (2 + keylen + 2 + vallen + 2 < pktsize) { + memcpy(&ss, buf + 8 + keylen + vallen , 2); + if (6+keylen+vallen+ss > pktsize) continue; + expires = uwsgi_str_num(buf + 10 + keylen+vallen, ss); + } uwsgi_wlock(uwsgi.cache_lock); - if (uwsgi_cache_set(key, keylen, val, vallen, 0, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_LOCAL)) { + if (uwsgi_cache_set(key, keylen, val, vallen, expires, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_LOCAL|UWSGI_CACHE_FLAG_ABSEXPIRE)) { uwsgi_log("[cache-udp-server] unable to update cache\n"); } uwsgi_rwunlock(uwsgi.cache_lock); diff --git a/uwsgi.h b/uwsgi.h index e6d6c155..06a5f0cf 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -287,6 +287,7 @@ extern int pivot_root(const char *new_root, const char *put_old); #define UWSGI_CACHE_FLAG_UNGETTABLE 0x0001 #define UWSGI_CACHE_FLAG_UPDATE 0x0002 #define UWSGI_CACHE_FLAG_LOCAL 0x0004 +#define UWSGI_CACHE_FLAG_ABSEXPIRE 0x0008 #define uwsgi_cache_update_start(x, y, z) uwsgi_cache_set(x, y, "", 0, CACHE_FLAG_UNGETTABLE)