aboutsummaryrefslogtreecommitdiffstats
path: root/erts/epmd/src
diff options
context:
space:
mode:
Diffstat (limited to 'erts/epmd/src')
-rw-r--r--erts/epmd/src/epmd.h1
-rw-r--r--erts/epmd/src/epmd_int.h10
-rw-r--r--erts/epmd/src/epmd_srv.c89
3 files changed, 59 insertions, 41 deletions
diff --git a/erts/epmd/src/epmd.h b/erts/epmd/src/epmd.h
index cffcd4ae7a..7332294d3d 100644
--- a/erts/epmd/src/epmd.h
+++ b/erts/epmd/src/epmd.h
@@ -26,6 +26,7 @@
#define EPMD_ALIVE2_REQ 'x'
#define EPMD_PORT2_REQ 'z'
#define EPMD_ALIVE2_RESP 'y'
+#define EPMD_ALIVE2_X_RESP 'v'
#define EPMD_PORT2_RESP 'w'
#define EPMD_NAMES_REQ 'n'
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index ed9bbdb8cd..a5156a142e 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -277,6 +277,12 @@ static const struct in6_addr in6addr_loopback =
#define put_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \
((unsigned char*)(s))[1] = (i) & 0xff;}
+#define put_int32(i, s) do {((char*)(s))[0] = (char)((i) >> 24) & 0xff; \
+ ((char*)(s))[1] = (char)((i) >> 16) & 0xff; \
+ ((char*)(s))[2] = (char)((i) >> 8) & 0xff; \
+ ((char*)(s))[3] = (char)(i) & 0xff;} \
+ while (0)
+
#if defined(__GNUC__)
# define EPMD_INLINE __inline__
#elif defined(__WIN32__)
@@ -307,10 +313,10 @@ struct enode {
int fd; /* The socket in use */
unsigned short port; /* Port number of Erlang node */
char symname[MAXSYMLEN+1]; /* Name of the Erlang node */
- short creation; /* Started as a random number 1..3 */
+ unsigned int cr_counter; /* Used to generate 'creation' numbers */
char nodetype; /* 77 = normal erlang node 72 = hidden (c-node */
char protocol; /* 0 = tcp/ipv4 */
- unsigned short highvsn; /* 0 = OTP-R3 erts-4.6.x, 1 = OTP-R4 erts-4.7.x*/
+ unsigned short highvsn; /* 5: creation=1..3, 6: creation=1..(2^32-1)*/
unsigned short lowvsn;
int extralen;
char extra[MAXSYMLEN+1];
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 3c6f1fbdf4..633ec71e5f 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -665,6 +665,21 @@ static int do_accept(EpmdVars *g,int listensock)
return conn_open(g,msgsock);
}
+static void bump_creation(Node* node)
+{
+ if (++node->cr_counter == 0)
+ node->cr_counter = 1;
+}
+static unsigned int get_creation(Node* node)
+{
+ if (node->highvsn >= 6) {
+ return node->cr_counter; /* 1..(2^32-1)*/
+ }
+ else {
+ return (node->cr_counter - 1) % 3 + 1; /* 1..3 */
+ }
+}
+
/* buf is actually one byte larger than bsize,
giving place for null termination */
static void do_request(g, fd, s, buf, bsize)
@@ -706,8 +721,10 @@ static void do_request(g, fd, s, buf, bsize)
unsigned char protocol;
unsigned short highvsn;
unsigned short lowvsn;
+ unsigned int creation;
int namelen;
int extralen;
+ int replylen;
char *name;
char *extra;
eport = get_int16(&buf[1]);
@@ -737,17 +754,22 @@ static void do_request(g, fd, s, buf, bsize)
extra = &buf[11+namelen+2];
extra[extralen]='\000';
- wbuf[0] = EPMD_ALIVE2_RESP;
- if ((node = node_reg2(g, namelen, name, fd, eport, nodetype, protocol,
- highvsn, lowvsn, extralen, extra)) == NULL) {
- wbuf[1] = 1; /* error */
- put_int16(99, wbuf+2);
- } else {
- wbuf[1] = 0; /* ok */
- put_int16(node->creation, wbuf+2);
- }
+ node = node_reg2(g, namelen, name, fd, eport, nodetype, protocol,
+ highvsn, lowvsn, extralen, extra);
+ creation = node ? get_creation(node) : 99;
+ wbuf[1] = node ? 0 : 1; /* ok | error */
+ if (highvsn >= 6) {
+ wbuf[0] = EPMD_ALIVE2_X_RESP;
+ put_int32(creation, wbuf+2);
+ replylen = 6;
+ }
+ else {
+ wbuf[0] = EPMD_ALIVE2_RESP;
+ put_int16(creation, wbuf+2);
+ replylen = 4;
+ }
- if (!reply(g, fd, wbuf, 4))
+ if (!reply(g, fd, wbuf, replylen))
{
node_unreg(g, name);
dbg_tty_printf(g,1,"** failed to send ALIVE2_RESP for \"%s\"",
@@ -1200,8 +1222,8 @@ static int node_unreg(EpmdVars *g,char *name)
for (; node; prev = &node->next, node = node->next)
if (is_same_str(node->symname, name))
{
- dbg_tty_printf(g,1,"unregistering '%s:%d', port %d",
- node->symname, node->creation, node->port);
+ dbg_tty_printf(g,1,"unregistering '%s:%u', port %d",
+ node->symname, get_creation(node), node->port);
*prev = node->next; /* Link out from "reg" list */
@@ -1235,8 +1257,8 @@ static int node_unreg_sock(EpmdVars *g,int fd)
for (; node; prev = &node->next, node = node->next)
if (node->fd == fd)
{
- dbg_tty_printf(g,1,"unregistering '%s:%d', port %d",
- node->symname, node->creation, node->port);
+ dbg_tty_printf(g,1,"unregistering '%s:%u', port %d",
+ node->symname, get_creation(node), node->port);
*prev = node->next; /* Link out from "reg" list */
@@ -1264,19 +1286,8 @@ static int node_unreg_sock(EpmdVars *g,int fd)
}
/*
- * Finding a node slot and a (name,creation) name is a bit tricky.
- * We try in order
- *
- * 1. If the name was used before and we can reuse that slot but use
- * a new "creation" digit in the range 1..3.
- *
- * 2. We try to find a new unused slot.
- *
- * 3. We try to use an used slot this isn't used any longer.
- * FIXME: The criteria for *what* slot to steal should be improved.
- * Perhaps use the oldest or something.
+ * Register a new node
*/
-
static Node *node_reg2(EpmdVars *g,
int namelen,
char* name,
@@ -1346,7 +1357,7 @@ static Node *node_reg2(EpmdVars *g,
}
/* Try to find the name in the used queue so that we
- can change "creation" number 1..3 */
+ can change "creation" number */
prev = NULL;
@@ -1375,9 +1386,8 @@ static Node *node_reg2(EpmdVars *g,
g->nodes.unreg_count--;
- /* When reusing we change the "creation" number 1..3 */
-
- node->creation = node->creation % 3 + 1;
+ /* When reusing we change the "creation" number */
+ bump_creation(node);
break;
}
@@ -1404,7 +1414,8 @@ static Node *node_reg2(EpmdVars *g,
exit(1);
}
- node->creation = (current_time(g) % 3) + 1; /* "random" 1-3 */
+ node->cr_counter = current_time(g); /* "random" */
+ bump_creation(node);
}
}
@@ -1423,11 +1434,11 @@ static Node *node_reg2(EpmdVars *g,
select_fd_set(g, fd);
if (highvsn == 0) {
- dbg_tty_printf(g,1,"registering '%s:%d', port %d",
- node->symname, node->creation, node->port);
+ dbg_tty_printf(g,1,"registering '%s:%u', port %d",
+ node->symname, get_creation(node), node->port);
} else {
- dbg_tty_printf(g,1,"registering '%s:%d', port %d",
- node->symname, node->creation, node->port);
+ dbg_tty_printf(g,1,"registering '%s:%u', port %d",
+ node->symname, get_creation(node), node->port);
dbg_tty_printf(g,1,"type %d proto %d highvsn %d lowvsn %d",
nodetype, protocol, highvsn, lowvsn);
}
@@ -1561,8 +1572,8 @@ static void print_names(EpmdVars *g)
for (node = g->nodes.reg; node; node = node->next)
{
- fprintf(stderr,"***** active name \"%s#%d\" at port %d, fd = %d\r\n",
- node->symname, node->creation, node->port, node->fd);
+ fprintf(stderr,"***** active name \"%s#%u\" at port %d, fd = %d\r\n",
+ node->symname, get_creation(node), node->port, node->fd);
count ++;
}
@@ -1572,8 +1583,8 @@ static void print_names(EpmdVars *g)
for (node = g->nodes.unreg; node; node = node->next)
{
- fprintf(stderr,"***** old/unused name \"%s#%d\"\r\n",
- node->symname, node->creation);
+ fprintf(stderr,"***** old/unused name \"%s#%u\"\r\n",
+ node->symname, get_creation(node));
count ++;
}