codedge-llc / pigeon

iOS and Android push notifications for Elixir
https://hex.pm/packages/pigeon
MIT License
606 stars 133 forks source link

Kadabra crashes on revoked APNS certificate #200

Open SteamRiC opened 3 years ago

SteamRiC commented 3 years ago

Environment

Elixir 1.11.3 (compiled with Erlang/OTP 21)

* Operating system:  macOS Big Sur, Version 11.2.1

### Current behavior
Wasn't sure if I should create the issue for kadabra or pigeon, but since this happens for me when trying to send push notifications, added it here.

This happens for me in my dev environment as well as in production.

To reproduce, revoke your APNS credentials from Apple's developer portal (from my experience, it takes ~24h until Apple actually starts rejecting the requests) and attempt to send a push notification. The following errors can be seen in logs:

<details>
  <summary>Click to expand!</summary>

[error] GenServer #PID<0.785.0> terminating (FunctionClauseError) no function clause matching in Kadabra.Socket.handle_info/2 (kadabra 0.6.0) lib/socket.ex:174: Kadabra.Socket.handle_info({:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.782.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Last message: {:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}} State: %Kadabra.Socket{active_user: #PID<0.782.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}} file=gen_server.erl function=error_info/7 line=943 module=gen_server pid=<0.785.0> [error] Process #PID<0.785.0> terminating (FunctionClauseError) no function clause matching in Kadabra.Socket.handle_info/2 (kadabra 0.6.0) lib/socket.ex:174: Kadabra.Socket.handle_info({:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.782.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.787.0>, #PID<0.786.0>]}}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Initial Call: Kadabra.Socket.init/1 Ancestors: [#PID<0.782.0>, #PID<0.781.0>, :kadabra, #PID<0.587.0>] Message Queue Length: 0 Messages: [] Links: [#PID<0.782.0>] Dictionary: [] Trapping Exits: false Status: :running Heap Size: 4185 Stack Size: 28 Reductions: 28650 file=proc_lib.erl function=crash_report/4 line=525 module=proc_lib pid=<0.785.0>

</details>

<details>
  <summary>Click to expand!</summary>

[error] GenServer #PID<0.827.0> terminating (FunctionClauseError) no function clause matching in Kadabra.Connection.handle_info/2 (kadabra 0.6.0) lib/connection.ex:128: Kadabra.Connection.handle_info({:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, 129, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, 103, 239, 24, 29, 195, 155, 61, 11, 111, 24, 224, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Last message: {:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}} State: %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, 129, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, 103, 239, 24, 29, 195, 155, 61, 11, 111, 24, 224, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0} file=gen_server.erl function=error_info/7 line=943 module=gen_server pid=<0.827.0> [error] Process #PID<0.827.0> terminating (FunctionClauseError) no function clause matching in Kadabra.Connection.handle_info/2 (kadabra 0.6.0) lib/connection.ex:128: Kadabra.Connection.handle_info({:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, 129, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, 103, 239, 24, 29, 195, 155, 61, 11, 111, 24, 224, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Initial Call: Kadabra.Connection.init/1 Ancestors: [#PID<0.826.0>, :kadabra, #PID<0.632.0>] Message Queue Length: 0 Messages: [] Links: [#PID<0.828.0>, #PID<0.829.0>, #PID<0.826.0>] Dictionary: [] Trapping Exits: true Status: :running Heap Size: 6772 Stack Size: 28 Reductions: 36300 Neighbours:

PID<0.829.0>

    Initial Call: Kadabra.Hpack.init/1
    Current Call: :gen_server.loop/7
    Ancestors: [#PID<0.827.0>, #PID<0.826.0>, :kadabra, #PID<0.632.0>]
    Message Queue Length: 0
    Links: [#PID<0.827.0>]
    Trapping Exits: false
    Status: :waiting
    Heap Size: 233
    Stack Size: 12
    Reductions: 40
    Current Stacktrace:
        (stdlib 3.14) gen_server.erl:437: :gen_server.loop/7
        (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
#PID<0.828.0>
    Initial Call: Kadabra.Hpack.init/1
    Current Call: :gen_server.loop/7
    Ancestors: [#PID<0.827.0>, #PID<0.826.0>, :kadabra, #PID<0.632.0>]
    Message Queue Length: 0
    Links: [#PID<0.827.0>]
    Trapping Exits: false
    Status: :waiting
    Heap Size: 233
    Stack Size: 12
    Reductions: 40
    Current Stacktrace:
        (stdlib 3.14) gen_server.erl:437: :gen_server.loop/7
        (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 file=proc_lib.erl function=crash_report/4 line=525 module=proc_lib pid=<0.827.0>
</details>

<details>
  <summary>Click to expand!</summary>

[error] GenServer #PID<0.826.0> terminating (FunctionClauseError) no function clause matching in Kadabra.ConnectionPool.handle_info/2 (kadabra 0.6.0) lib/connection_pool.ex:93: Kadabra.ConnectionPool.handle_info({:EXIT, #PID<0.827.0>, {:function_clause, [{Kadabra.Connection, :handle_info, [{:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}], [file: 'lib/connection.ex', line: 128]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.ConnectionPool{connection: #PID<0.827.0>, events: [], pending_demand: 0}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Last message: {:EXIT, #PID<0.827.0>, {:function_clause, [{Kadabra.Connection, :handle_info, [{:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}], [file: 'lib/connection.ex', line: 128]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}} State: %Kadabra.ConnectionPool{connection: #PID<0.827.0>, events: [], pending_demand: 0} file=gen_server.erl function=error_info/7 line=943 module=gen_server pid=<0.826.0> [error] Process #PID<0.826.0> terminating (FunctionClauseError) no function clause matching in Kadabra.ConnectionPool.handle_info/2 (kadabra 0.6.0) lib/connection_pool.ex:93: Kadabra.ConnectionPool.handle_info({:EXIT, #PID<0.827.0>, {:function_clause, [{Kadabra.Connection, :handle_info, [{:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}], [file: 'lib/connection.ex', line: 128]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.ConnectionPool{connection: #PID<0.827.0>, events: [], pending_demand: 0}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Initial Call: Kadabra.ConnectionPool.init/1 Ancestors: [:kadabra, #PID<0.632.0>] Message Queue Length: 0 Messages: [] Links: [#PID<0.633.0>] Dictionary: [] Trapping Exits: true Status: :running Heap Size: 6772 Stack Size: 28 Reductions: 42088 file=proc_lib.erl function=crash_report/4 line=525 module=proc_lib pid=<0.826.0>

</details>

<details>
  <summary>Click to expand!</summary>

[error] Child #Reference<0.1867489447.1854930945.37039> of Supervisor :kadabra terminated (exit) an exception was raised: (FunctionClauseError) no function clause matching in Kadabra.ConnectionPool.handle_info/2 (kadabra 0.6.0) lib/connection_pool.ex:93: Kadabra.ConnectionPool.handle_info({:EXIT, #PID<0.827.0>, {:function_clause, [{Kadabra.Connection, :handle_info, [{:EXIT, #PID<0.830.0>, {:function_clause, [{Kadabra.Socket, :handle_info, [{:ssl_error, {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}, {:tls_alert, {:certificate_revoked, 'TLS client: In state connection received SERVER ALERT: Fatal - Certificate Revoked\n'}}}, %Kadabra.Socket{active_user: #PID<0.827.0>, buffer: "", socket: {:sslsocket, {:gen_tcp, #Port<0.50>, :tls_connection, :undefined}, [#PID<0.832.0>, #PID<0.831.0>]}}], [file: 'lib/socket.ex', line: 174]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.Connection{buffer: "", config: %Kadabra.Config{client: #PID<0.809.0>, decoder: #PID<0.829.0>, encoder: #PID<0.828.0>, opts: [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]], queue: #PID<0.826.0>, socket: #PID<0.830.0>, uri: %URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}}, flow_control: %Kadabra.Connection.FlowControl{initial_window_size: 65535, max_frame_size: 16384, queue: {[], []}, stream_set: %Kadabra.StreamSet{active_stream_count: 0, active_streams: %{}, max_concurrent_streams: :infinite, stream_id: 1}, window: 65535}, local_settings: %Kadabra.Connection.Settings{enable_push: true, header_table_size: 4096, initial_window_size: 2147483647, max_concurrent_streams: :infinite, max_frame_size: 16777215, max_header_list_size: nil}, queue: #PID<0.826.0>, remote_settings: nil, remote_window: 65535, requested_streams: 0}], [file: 'lib/connection.ex', line: 128]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 689]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 765]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}, %Kadabra.ConnectionPool{connection: #PID<0.827.0>, events: [], pending_demand: 0}) (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4 (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6 (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 Pid: #PID<0.826.0> Start Call: Kadabra.ConnectionPool.start_link(%URI{authority: "api.development.push.apple.com", fragment: nil, host: "api.development.push.apple.com", path: nil, port: 443, query: nil, scheme: "https", userinfo: nil}, #PID<0.809.0>, [ssl: [{:cert, <<48, 130, 5, 120, 48, 130, 4, 96, 160, 3, 2, 1, 2, 2, 8, 50, 31, 4, 222, 132, 188, 37, 3, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, 129, 150, 49, 11, 48, 9, 6, ...>>}, {:key, {:RSAPrivateKey, <<48, 130, 4, 164, 2, 1, 0, 2, 130, 1, 1, 0, 215, 60, 74, 249, 84, 12, 223, 163, 58, 176, 203, 223, 102, 176, 103, 239, 24, 29, 195, 155, 61, 11, 111, 24, 224, 27, 57, 144, 195, 70, 132, ...>>}}, {:password, []}, {:packet, 0}, {:reuseaddr, true}, {:active, true}, :binary]]) Restart: :transient Shutdown: 5000 Type: :worker file=supervisor.erl function=do_restart/3 line=719 module=supervisor pid=<0.633.0>


 </details>

 After that kadabra has crashed and needs to be restarted before another attempt to send a push notification can be made.

`Pigeon.APNS.start_connection(mode: "sandbox")` seems to succeed just fine but calling `Pigeon.APNS.push(notification, to: connection_pid)` causes the crash.

### Expected behavior

An error is returned when attempting to start a connector or when sending a push notification.
BrendanBall commented 2 years ago

Hi, we have also experienced, although with a slightly different error. This caused a cascading failure and resulted in a full node restart because kadabra starts its own application. From what I've read, it seems to be a bit of an anti pattern for libraries to start their own applications because the library user is unable to control how failures affect their system by starting the library in the user's own supervision tree (see https://elixirforum.com/t/preventing-cascading-failure-of-library-application-taking-whole-node-down/44088 for more context). I've made myself more familiar with the pigeon codebase and it seems that pigeon v2 is already partially fixing this by allowing users to add Dispatchers to their own supervision tree. Unfortunately this still wouldn't fix this problem because the crash happens in kadabra at connection time.

Do you agree that it would be better for the user to start the entire pigeon supervision tree under the user's supervision tree? If so, we can open an issue on kadabra and talk about the required changes there first since it has to be changed before pigeon can completely do this (I know that kadabra is done by the same people and it was implemented specifically for pigeon so it shouldn't be difficult to get consensus).

BrendanBall commented 2 years ago

@hpopp could you maybe comment on this? It seems to also be related to #203

Sinc63 commented 9 months ago

Expected behavior

An error is returned when attempting to start a connector or when sending a push notification.

I opened a PR against kadabra a couple years back. No merge yet, but it's been working for me. It just handles the ssl_error in a manner, although I've recently come to doubt the response I'm sending back. Pigeon still doesn't react to the returned value in a helpful way, so I'm mostly just stopped the FCE.