I appreciate this question is highly similar to another I asked yesterday. However, while the solution there works on MacOS, on Debian I am getting different errors, and a different set of problems.
First I create a new project with mix new tls_question. I have added :crypto and :ssl to mix.exs like so:
def application do
[
extra_applications: [:logger, :crypto, :ssl]
]
end
The badarg here is caused by do_connect not finding an address to bind to (the big when clause):
Based on the Compilation error in the message, I believe the issue is the TlsQuestion.main() on the last line - that tries to start the listener when the file is compiled. That’s not needed if you’re launching it with mix run 'TlsQuestion.main()'.
I tried running mix run 'TlsQuestion.main()' without changing the code. That gives the same error.
I then tried removing the line
TlsQuestion.main()
which gave the error:
Compiling 1 file (.ex)
** (Mix) No such file: TlsQuestion.main()
I then tried making a similar project.
defmodule Apptestversion.Application do
use Application
def start(_type, _args) do
children = [
Apptestversion,
]
opts = [strategy: :one_for_one, name: Apptestversion.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule TlsQuestion do
use GenServer
def start_link([] = _opts) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@impl true
def init(_) do
:ssl.start()
{:ok, listen_socket} = :ssl.listen(8000,
[ certs_keys: [%{
:keyfile => "key.pem",
:certfile => "cert.pem",
}],
reuseaddr: true,
])
end
end
which gives the error
** (Mix) Could not start application apptestversion: Apptestversion.Application.start(:normal, []) returned an error: shutdown: failed to start child: Apptestversion
** (EXIT) :badarg
I don’t believe reuseaddr is a valid listen option (according to Erlang -- gen_tcp)
Erlang SSL options can be confusing because they are all effectively included in the specs, but run through a very specific validation when attempting to run
I’ve taken a look and I’m pretty sure the option is in there. Here is what it’s for.
I have attempted to remove the option anyway to see if anything different happens and the answer is no.
You’re right. After a closer look, that option should be fine.
I tried the initial code you posted and it worked for me with mix run -e 'TlsQuestion.main(). I might suggest hardcoding full paths to the cert/key and testing again. Also, what OTP version are you using? :certs_keys is a newer option in OTP 25. I tried this same code with OTP 24 and got the same error you see which makes me believe that the badarg is referencing the certs_keys option and your lower OTP version.
I’m running OTP 21 on my Raspberry Pi. Is there an alternative way to get SSL working on OTP 21? I’ve rolled my own TLS 1.2 implementation before but that was in another language and I don’t fancy doing it again.
asdf install erlang latest gives me:
asdf_25.2.3 is not a kerl-managed Erlang/OTP installation
The asdf_25.2.3 build has been deleted
Extracting source code
Building Erlang/OTP 25.2.3 (asdf_25.2.3), please wait...
APPLICATIONS DISABLED (See: /home/freddiewoodruff/.asdf/plugins/erlang/kerl-home/builds/asdf_25.2.3/otp_build_25.2.3.log)
* jinterface : No Java compiler found
* odbc : ODBC library - link check failed
APPLICATIONS INFORMATION (See: /home/freddiewoodruff/.asdf/plugins/erlang/kerl-home/builds/asdf_25.2.3/otp_build_25.2.3.log)
* wx : No GLU headers found, wx will NOT be usable
* wxWidgets was not compiled with --enable-webview or wxWebView developer package is not installed, wxWebView will NOT be available
* wxWidgets must be installed on your system.
* Please check that wx-config is in path, the directory
* where wxWidgets libraries are installed (returned by
* 'wx-config --libs' or 'wx-config --static --libs' command)
* is in LD_LIBRARY_PATH or equivalent variable and
* wxWidgets version is 3.0.2 or above.
DOCUMENTATION INFORMATION (See: /home/freddiewoodruff/.asdf/plugins/erlang/kerl-home/builds/asdf_25.2.3/otp_build_25.2.3.log)
* documentation :
* xsltproc is missing.
* fop is missing.
* xmllint is missing.
* The documentation cannot be built.
then CCL seems to peg the CPU to 95% for hours. Attempts to install Java tell me ARMv6 isn’t good enough. It all suggests to me I’m stuck with OTP 21.
If not, just use the certfile and keyfile option directly which should work with OTP 21
If yes, do you need Java? That can be disabled. You would also need to install openSSL on the rpi and specify both of these in KERL_CONFIGURE_OPTIONS.
Internet search would probably serve up several sources that show how to compile for raspberry pi, but the just is you would need KERL_CONFIGURE_OPTIONS="--without-javac --with-ssl=/path/to/openssl/install"
OTP also has some documentation on compilation, including who to cross compile OTP for raspberry pi on MacOS (you may not have MacOS available, but this would at least be a good starting point to cross-compile)
The Erlang Forum may be the best place to find info and help for compiling OTP on raspberry pi
Also note that it will take hours and really peg the CPU of the raspberry pi just due to the design of the processor and intensity of the compilation
Are you using the whole raspberry pi OS? Or just to run Erlang/Elixir on it?
If you only need Erlang/Elixir, then Nerves is also an option. In a nutshell, it is all the tooling to compile a firmware and run the beam+Elixir app directly on devices and Raspberry pi is officially supported. OTP is already precompiled for you as part of the tooling (See HexDocs for more documentation)
This solves it thank you!!! Cool I’ll try that for installing Java. It might come in handy at some point.
I am currently using the whole Raspberry Pi OS. I can see you work at Nerves and I’ll take a look at it and spread the word!