• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

emqx / esockd / 527

16 Sep 2025 07:26AM UTC coverage: 67.052% (+1.0%) from 66.039%
527

push

github

web-flow
Merge pull request #211 from JimMoen/fix-rate-limit-pause

fix: the next check start time should be `Now + Pasue`

2 of 2 new or added lines in 1 file covered. (100.0%)

228 existing lines in 13 files now uncovered.

696 of 1038 relevant lines covered (67.05%)

106.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.14
/src/esockd_dtls_listener.erl
1
%%--------------------------------------------------------------------
2
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
3
%%
4
%% Licensed under the Apache License, Version 2.0 (the "License");
5
%% you may not use this file except in compliance with the License.
6
%% You may obtain a copy of the License at
7
%%
8
%%     http://www.apache.org/licenses/LICENSE-2.0
9
%%
10
%% Unless required by applicable law or agreed to in writing, software
11
%% distributed under the License is distributed on an "AS IS" BASIS,
12
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
%% See the License for the specific language governing permissions and
14
%% limitations under the License.
15
%%--------------------------------------------------------------------
16

17
-module(esockd_dtls_listener).
18

19
-behaviour(gen_server).
20

21
-include("esockd.hrl").
22

23
-export([start_link/4]).
24

25
-export([ options/1
26
        , get_port/1
27
        ]).
28

29
%% gen_server callbacks
30
-export([ init/1
31
        , handle_call/3
32
        , handle_cast/2
33
        , handle_info/2
34
        , terminate/2
35
        , code_change/3
36
        ]).
37

38
-record(state, {
39
          proto     :: atom(),
40
          listen_on :: esockd:listen_on(),
41
          options   :: [esockd:option()],
42
          lsock     :: ssl:sslsocket(),
43
          laddr     :: inet:ip_address(),
44
          lport     :: inet:port_number()
45
         }).
46

47
-define(ACCEPTOR_POOL, 8).
48
-define(DEFAULT_DTLS_OPTIONS,
49
        [{protocol, dtls},
50
         {mode, binary},
51
         {reuseaddr, true}]).
52

53
-spec(start_link(atom(), esockd:listen_on(), [esockd:option()], pid())
54
      -> {ok, pid()} | ignore | {error, term()}).
55
start_link(Proto, ListenOn, Opts, AcceptorSup) ->
56
    gen_server:start_link(?MODULE, {Proto, ListenOn, Opts, AcceptorSup}, []).
30✔
57

58
-spec(options(pid()) -> [esockd:option()]).
59
options(Listener) ->
UNCOV
60
    gen_server:call(Listener, options).
×
61

62
-spec(get_port(pid()) -> inet:port_number()).
63
get_port(Listener) ->
UNCOV
64
    gen_server:call(Listener, get_port).
×
65

66
%%--------------------------------------------------------------------
67
%% gen_server callbacks
68
%%--------------------------------------------------------------------
69

70
init({Proto, ListenOn, Opts, AcceptorSup}) ->
71
    Port = port(ListenOn),
30✔
72
    process_flag(trap_exit, true),
30✔
73
    SockOpts = merge_addr(ListenOn, dltsopts(Opts)),
30✔
74
    %% Don't active the socket...
75
    case ssl:listen(Port, SockOpts) of
30✔
76
    %%case ssl:listen(Port, [{active, false} | proplists:delete(active, SockOpts)]) of
77
        {ok, LSock} ->
78
            AcceptorNum = proplists:get_value(acceptors, Opts, ?ACCEPTOR_POOL),
30✔
79
            lists:foreach(fun (_) ->
30✔
80
                case esockd_dtls_acceptor_sup:start_acceptor(AcceptorSup, LSock) of
204✔
81
                    {ok, _APid} -> ok;
204✔
UNCOV
82
                    {error, Reason} -> exit({start_accepptors_failed, Reason})
×
83
                end
84
            end, lists:seq(1, AcceptorNum)),
85
            {ok, {LAddr, LPort}} = ssl:sockname(LSock),
30✔
86
            %%error_logger:info_msg("~s listen on ~s:~p with ~p acceptors.~n",
87
            %%                      [Proto, inet:ntoa(LAddr), LPort, AcceptorNum]),
88
            {ok, #state{proto = Proto, listen_on = ListenOn, options = Opts,
30✔
89
                        lsock = LSock, laddr = LAddr, lport = LPort}};
90
        {error, Reason} ->
UNCOV
91
            error_logger:error_msg("~s failed to listen on ~p - ~p (~s)",
×
92
                                   [Proto, Port, Reason, inet:format_error(Reason)]),
UNCOV
93
            {stop, Reason}
×
94
    end.
95

96
dltsopts(Opts) ->
97
    DtlsOpts = proplists:delete(
30✔
98
                 handshake_timeout,
99
                 proplists:get_value(dtls_options, Opts, [])
100
                ),
101
    esockd:merge_opts(?DEFAULT_DTLS_OPTIONS, DtlsOpts).
30✔
102

103
port(Port) when is_integer(Port) -> Port;
30✔
UNCOV
104
port({_Addr, Port}) -> Port.
×
105

106
merge_addr(Port, SockOpts) when is_integer(Port) ->
107
    SockOpts;
30✔
108
merge_addr({Addr, _Port}, SockOpts) ->
UNCOV
109
    lists:keystore(ip, 1, SockOpts, {ip, Addr}).
×
110

111
handle_call(options, _From, State = #state{options = Opts}) ->
112
    {reply, Opts, State};
3✔
113

114
handle_call(get_port, _From, State = #state{lport = LPort}) ->
UNCOV
115
    {reply, LPort, State};
×
116

117
handle_call(Req, _From, State) ->
UNCOV
118
    error_logger:error_msg("[~s] Unexpected call: ~p", [?MODULE, Req]),
×
UNCOV
119
    {noreply, State}.
×
120

121
handle_cast(Msg, State) ->
UNCOV
122
    error_logger:error_msg("[~s] Unexpected cast: ~p", [?MODULE, Msg]),
×
UNCOV
123
    {noreply, State}.
×
124

125
handle_info(Info, State) ->
UNCOV
126
    error_logger:error_msg("[~s] Unexpected info: ~p", [?MODULE, Info]),
×
127
    {noreply, State}.
×
128

129
terminate(_Reason, #state{proto = Proto, listen_on = ListenOn,
130
                          lsock = LSock, laddr = Addr, lport = Port}) ->
131
    error_logger:info_msg("~s stopped on ~s~n", [Proto, esockd:format({Addr, Port})]),
30✔
132
    esockd_limiter:delete({listener, Proto, ListenOn}),
30✔
133
    esockd_server:del_stats({Proto, ListenOn}),
30✔
134
    esockd_transport:fast_close(LSock).
30✔
135

136
code_change(_OldVsn, State, _Extra) ->
UNCOV
137
    {ok, State}.
×
138

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc