From 0970ffaf49129c21930b5a99eba0666f3ad0d5e1 Mon Sep 17 00:00:00 2001 From: Bryan Paxton Date: Mon, 4 Nov 2024 11:46:32 -0600 Subject: [PATCH] Delegate to :ssl for setopts/2 when transport is tls Previously we always called `:inet.setopts/2` when a timeout was detected to set `{linger, {true, 0}}` to immediately tear down the socket before closing the connection. In doing so and in the case of tls the sslsocket structure gets passed to `:prim_inet.setopts/2` where the first argument is expected to be a port identifier. --- .github/workflows/main.yml | 18 +++++++++--------- .tool-versions | 4 ++-- lib/mllp/client.ex | 2 +- lib/mllp/tcp.ex | 3 +++ lib/mllp/tls.ex | 3 +++ mix.exs | 2 +- mix.lock | 4 ++-- test/client_and_receiver_integration_test.exs | 2 +- 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e215d7d..0b7336d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,16 +9,16 @@ on: env: MIX_ENV: test - otp-version: '24' - elixir-version: '1.14' - cache-version: '4' + otp-version: '26' + elixir-version: '1.16.2' + cache-version: '6' jobs: build: strategy: matrix: - otp: ['24', '25'] - elixir: ['1.13', '1.14'] + otp: ['25', '26'] + elixir: ['1.15', '1.16'] name: Build runs-on: ubuntu-latest steps: @@ -74,8 +74,8 @@ jobs: needs: build strategy: matrix: - otp: ['24', '25'] - elixir: ['1.13', '1.14'] + otp: ['25', '26'] + elixir: ['1.15', '1.16'] name: Dialyzer runs-on: ubuntu-latest steps: @@ -108,8 +108,8 @@ jobs: needs: build strategy: matrix: - otp: ['24', '25'] - elixir: ['1.13', '1.14'] + otp: ['25', '26'] + elixir: ['1.15', '1.16'] name: Test runs-on: ubuntu-latest steps: diff --git a/.tool-versions b/.tool-versions index 94619c2..a4afa5f 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -elixir 1.14.2 -erlang 25.2 +elixir 1.16.1 +erlang 26.2.5 diff --git a/lib/mllp/client.ex b/lib/mllp/client.ex index c822e94..8a43139 100644 --- a/lib/mllp/client.ex +++ b/lib/mllp/client.ex @@ -733,7 +733,7 @@ defmodule MLLP.Client do Logger.debug("Stopping connection: #{format_error(error)}") if error in [:timeout, :unexpected_packet_received] do - :ok = :inet.setopts(socket, linger: {true, 0}) + :ok = tcp.setopts(socket, linger: {true, 0}) tcp.shutdown(socket, :read_write) else tcp.close(socket) diff --git a/lib/mllp/tcp.ex b/lib/mllp/tcp.ex index 77377fc..0ca9ecb 100644 --- a/lib/mllp/tcp.ex +++ b/lib/mllp/tcp.ex @@ -1,4 +1,6 @@ defmodule MLLP.TCPContract do + @callback setopts(socket :: :gen_tcp.socket(), options :: [:gen_tcp.option()]) :: + :ok | {:error, :inet.posix()} @callback send(socket :: :gen_tcp.socket(), packet :: iodata()) :: :ok | {:error, any} @callback recv(socket :: :gen_tcp.socket(), length :: integer()) :: {:ok, any} | {:error, any} @callback recv(socket :: :gen_tcp.socket(), length :: integer(), timeout :: integer()) :: @@ -17,6 +19,7 @@ end defmodule MLLP.TCP do @behaviour MLLP.TCPContract + defdelegate setopts(socket, opts), to: :inet defdelegate send(socket, packet), to: :gen_tcp defdelegate recv(socket, length), to: :gen_tcp defdelegate recv(socket, length, timeout), to: :gen_tcp diff --git a/lib/mllp/tls.ex b/lib/mllp/tls.ex index 89b66df..cc9236b 100644 --- a/lib/mllp/tls.ex +++ b/lib/mllp/tls.ex @@ -1,4 +1,6 @@ defmodule MLLP.TLSContract do + @callback setopts(socket :: :ssl.sslsocket(), options :: [:gen_tcp.option()]) :: + :ok | {:error, term()} @callback send(socket :: :ssl.sslsocket(), packet :: iodata()) :: :ok | {:error, any} @callback recv(socket :: :ssl.sslsocket(), length :: integer()) :: {:ok, any} | {:error, any} @callback recv(socket :: :ssl.sslsocket(), length :: integer(), timeout :: integer()) :: @@ -17,6 +19,7 @@ end defmodule MLLP.TLS do @behaviour MLLP.TLSContract + defdelegate setopts(socket, opts), to: :ssl defdelegate send(socket, packet), to: :ssl defdelegate recv(socket, length), to: :ssl defdelegate recv(socket, length, timeout), to: :ssl diff --git a/mix.exs b/mix.exs index 0a2df97..1e45417 100644 --- a/mix.exs +++ b/mix.exs @@ -39,7 +39,7 @@ defmodule MLLP.MixProject do {:elixir_hl7, "~> 0.8.0"}, {:backoff, "~> 1.1.6"}, {:ex_doc, "~> 0.24.2", only: :dev, runtime: false}, - {:dialyxir, "~> 1.1.0", only: [:dev, :test], runtime: false}, + {:dialyxir, "~> 1.4.4", only: [:dev, :test], runtime: false}, {:mix_test_watch, "~> 1.0.2", only: :dev, runtime: false}, {:mox, "~> 1.0.0", only: :test}, {:excoveralls, "~> 0.14.4", only: :test, runtime: false} diff --git a/mix.lock b/mix.lock index adc900b..6f309be 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,10 @@ %{ "backoff": {:hex, :backoff, "1.1.6", "83b72ed2108ba1ee8f7d1c22e0b4a00cfe3593a67dbc792799e8cce9f42f796b", [:rebar3], [], "hexpm", "cf0cfff8995fb20562f822e5cc47d8ccf664c5ecdc26a684cbe85c225f9d7c39"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, - "dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"}, + "dialyxir": {:hex, :dialyxir, "1.4.4", "fb3ce8741edeaea59c9ae84d5cec75da00fa89fe401c72d6e047d11a61f65f70", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "cd6111e8017ccd563e65621a4d9a4a1c5cd333df30cebc7face8029cacb4eff6"}, "earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"}, "elixir_hl7": {:hex, :elixir_hl7, "0.8.0", "172b6fb68facc9fe68389746004ca6fddda4ae9c97c5ff6319f22fae56186d0c", [:mix], [], "hexpm", "5f067a58e02ce88ef50394e3f39a256c2780290ce1105715dc339670b6ac1b89"}, - "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"}, "excoveralls": {:hex, :excoveralls, "0.14.6", "610e921e25b180a8538229ef547957f7e04bd3d3e9a55c7c5b7d24354abbba70", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "0eceddaa9785cfcefbf3cd37812705f9d8ad34a758e513bb975b081dce4eb11e"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, diff --git a/test/client_and_receiver_integration_test.exs b/test/client_and_receiver_integration_test.exs index 5b57289..99ab1ba 100644 --- a/test/client_and_receiver_integration_test.exs +++ b/test/client_and_receiver_integration_test.exs @@ -580,7 +580,7 @@ defmodule ClientAndReceiverIntegrationTest do @tag client_cert: "tls/server/server_certificate.pem" @tag keyfile: "tls/server/private_key.pem" - @tag reason: [:handshake_failure] + @tag reason: [:unsupported_certificate] test "reject server cert as peer cert", ctx do make_call_and_assert_failure(ctx, ctx.expected_error_reasons) end