Where are my cookies?

Brujo Benavides
Erlang Battleground
3 min readMay 26, 2016

--

Continuing with the saga of particular curiosities and strange things from the Erlang World, let’s talk today about distributed Erlang. What I’m going to show you today was discovered by @rtraschke a while back and even when I kinda have an understanding of what’s going on I’m not sure I can explain it completely. If you can, by all means write the explanation down in the comments :)

The Basics

As stated in the docs

Each node has its own magic cookie, which is an Erlang atom.
When a node tries to connect to another node, the magic cookies are compared. If they do not match, the connected node rejects the connection.

To achieve this, you can start your nodes with proper command line arguments, and use erlang:get_cookie/0 to retrieve the cookie, as you can see here:

$ erl -name brujo -setcookie da-cookie

(brujo@computer.local)1> erlang:get_cookie().
da-cookie
(brujo@computer.local)2>

Simple enough, right? Don’t worry, it’ll get strange pretty easily…

Cookie Monster, Sesame Street

Messing up with the Cookies

The example above was really basic, let’s see what happens when we want to add more parameters to our command line:

$ erl -name brujo -setcookie da-cookie +A +P 10000

(brujo@computer.local)1> erlang:get_cookie().
‘QBDKZORZZXKMUKGGSZFE’
(brujo@computer.local)2>

That atom (‘QBDKZORZZXKMUKGGSZFE’) is actually an auto-generated cookie that’s stored in my ~/.erlang.cookie file. The question is why is erl not using the cookie I provided. I’ll try to explain that later, but let’s check 3 other weird scenarios first…

Let’s see what happens if we move that +A argument around a bit…

$ erl -name brujo +A -setcookie da-cookie +P 10000

1> erlang:get_cookie().
nocookie
2>

Woah! No cookies at all, not even a node name!
What if we provide no cookie at all?

$ erl -name brujo -setcookie +A +P 10000

(brujo@computer.local)1> erlang:get_cookie().
‘10000’
(brujo@computer.local)2>

Ok, that’s… unexpected.
What if we don’t even provide that +P parameter?

$ erl -name brujo -setcookie +A
Missing argument(s) for ‘+A’.

Now it fails!

What’s going on here?

Just like last time, please try to figure this one out by yourself before reading further. It’s not an easy thing to do, but it will be a somewhat rewarding experience, I promise.

Ok, you figured out? Excellent! Let’s see if your theory matches mine…

I got to admit this time that I haven’t tried to verify my theory by looking at erl’s code, because as far as I know it’s written in C and I’m no C programmer at all. So, what I’ve got today is just a theory, developed through inception. That means that I extrapolated a couple of examples and I came up with a conclusion that explains them and hopefully any other similar scenario.

These things I know for sure:

  • The problems are all bound to how erl is parsing its arguments.
  • +A requires an additional value, that we’re not providing.
  • erl will always boot up an Erlang VM, regardless of the correctness of the arguments you use in your command line.

So, by the looks of it, my conclusion is that erl’s command-line parsing procedure is something like this:

  • check every parameter in order, from left to right
  • if the parameter requires a value, pick the next non-parameter portion of the command line
    - if you it’s a valid value (i.e. +A requires a numeric value), keep moving
    - if you it’s an invalid value, just stop parsing and boot up the node
    - if you just can’t find it, report the error in the console

It looks like a very strange way of parsing command line arguments, indeed.

--

--