summaryrefslogtreecommitdiff
path: root/memcached.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-08-06 22:53:56 -0700
committerdormando <dormando@rydia.net>2022-08-24 22:32:40 -0700
commit2bdf0ec3c8d89d7b75cb8ba7f1290cd937595669 (patch)
tree5d0c0a4222b99237b2490d4bb082876c8a96a43d /memcached.c
parentacb89505d3361d025be112a958a0c45ece0135fd (diff)
downloadmemcached-2bdf0ec3c8d89d7b75cb8ba7f1290cd937595669.tar.gz
core: add tagging to listener sockets
-l tag[asdfasdf]:0.0.0.0:11211 not presently used for anything outside of the proxy code.
Diffstat (limited to 'memcached.c')
-rw-r--r--memcached.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/memcached.c b/memcached.c
index 154f2cf..1ee5205 100644
--- a/memcached.c
+++ b/memcached.c
@@ -647,7 +647,7 @@ void conn_io_queue_return(io_pending_t *io) {
conn *conn_new(const int sfd, enum conn_states init_state,
const int event_flags,
const int read_buffer_size, enum network_transport transport,
- struct event_base *base, void *ssl) {
+ struct event_base *base, void *ssl, uint64_t conntag) {
conn *c;
assert(sfd >= 0 && sfd < max_fds);
@@ -694,6 +694,7 @@ conn *conn_new(const int sfd, enum conn_states init_state,
c->transport = transport;
c->protocol = settings.binding_protocol;
+ c->tag = conntag;
/* unix socket mode doesn't need this, so zeroed out. but why
* is this done for every command? presumably for UDP
@@ -3072,7 +3073,7 @@ static void drive_machine(conn *c) {
#endif
dispatch_conn_new(sfd, conn_new_cmd, EV_READ | EV_PERSIST,
- READ_BUFFER_CACHED, c->transport, ssl_v);
+ READ_BUFFER_CACHED, c->transport, ssl_v, c->tag);
}
stop = true;
@@ -3472,7 +3473,8 @@ static void maximize_sndbuf(const int sfd) {
static int server_socket(const char *interface,
int port,
enum network_transport transport,
- FILE *portnumber_file, bool ssl_enabled) {
+ FILE *portnumber_file, bool ssl_enabled,
+ uint64_t conntag) {
int sfd;
struct linger ling = {0, 0};
struct addrinfo *ai;
@@ -3614,12 +3616,12 @@ static int server_socket(const char *interface,
}
dispatch_conn_new(per_thread_fd, conn_read,
EV_READ | EV_PERSIST,
- UDP_READ_BUFFER_SIZE, transport, NULL);
+ UDP_READ_BUFFER_SIZE, transport, NULL, conntag);
}
} else {
if (!(listen_conn_add = conn_new(sfd, conn_listening,
EV_READ | EV_PERSIST, 1,
- transport, main_base, NULL))) {
+ transport, main_base, NULL, conntag))) {
fprintf(stderr, "failed to create listening connection\n");
exit(EXIT_FAILURE);
}
@@ -3642,6 +3644,7 @@ static int server_socket(const char *interface,
static int server_sockets(int port, enum network_transport transport,
FILE *portnumber_file) {
bool ssl_enabled = false;
+ uint64_t conntag = 0;
#ifdef TLS
const char *notls = "notls";
@@ -3649,7 +3652,7 @@ static int server_sockets(int port, enum network_transport transport,
#endif
if (settings.inter == NULL) {
- return server_socket(settings.inter, port, transport, portnumber_file, ssl_enabled);
+ return server_socket(settings.inter, port, transport, portnumber_file, ssl_enabled, conntag);
} else {
// tokenize them and bind to each one of them..
char *b;
@@ -3680,6 +3683,35 @@ static int server_sockets(int port, enum network_transport transport,
}
#endif
+ const char *tagstr = "tag";
+ if (strncmp(p, "tag", strlen(tagstr)) == 0) {
+ p += strlen(tagstr);
+ if (*p == '[') {
+ char *e = strchr(p, ']');
+ if (e == NULL) {
+ fprintf(stderr, "Invalid tag in socket config: \"%s\"\n", p);
+ free(list);
+ return 1;
+ }
+ char *st = ++p; // skip '['
+ *e = '\0';
+ size_t len = e - st;
+ p = ++e; // skip ']'
+ p++; // skip an assumed ':'
+
+ // validate the tag and copy it in.
+ if (len > 8 || len < 1) {
+ fprintf(stderr, "Listener tags must be between 1 and 8 characters: \"%s\"\n", st);
+ free(list);
+ return 1;
+ }
+
+ // C programmers love turning string comparisons into
+ // integer comparisons.
+ memcpy(&conntag, st, len);
+ }
+ }
+
char *h = NULL;
if (*p == '[') {
// expecting it to be an IPv6 address enclosed in []
@@ -3705,7 +3737,7 @@ static int server_sockets(int port, enum network_transport transport,
*s = '\0';
++s;
if (!safe_strtol(s, &the_port)) {
- fprintf(stderr, "Invalid port number: \"%s\"", s);
+ fprintf(stderr, "Invalid port number: \"%s\"\n", s);
free(list);
return 1;
}
@@ -3718,7 +3750,7 @@ static int server_sockets(int port, enum network_transport transport,
if (strcmp(p, "*") == 0) {
p = NULL;
}
- ret |= server_socket(p, the_port, transport, portnumber_file, ssl_enabled);
+ ret |= server_socket(p, the_port, transport, portnumber_file, ssl_enabled, conntag);
if (ret != 0 && errno_save == 0) errno_save = errno;
}
free(list);
@@ -3798,7 +3830,7 @@ static int server_socket_unix(const char *path, int access_mask) {
}
if (!(listen_conn = conn_new(sfd, conn_listening,
EV_READ | EV_PERSIST, 1,
- local_transport, main_base, NULL))) {
+ local_transport, main_base, NULL, 0))) {
fprintf(stderr, "failed to create listening connection\n");
exit(EXIT_FAILURE);
}