4545 lsock :: ssl :sslsocket (),
4646 laddr :: inet :ip_address (),
4747 lport :: inet :port_number (),
48- sockopts :: [ssl :tls_server_option ()]
48+ sockopts :: [gen_udp :option ()],
49+ dtlsopts :: [ssl :tls_server_option ()]
4950 }).
5051
5152-type option () :: {dtls_options , [gen_udp :option ()]}.
5253
53- -define (DEFAULT_DTLS_OPTIONS ,
54- [{protocol , dtls },
55- {mode , binary },
54+ -define (DEFAULT_SOCK_OPTIONS ,
55+ [{mode , binary },
5656 {reuseaddr , true }]).
5757
58+ -define (DEFAULT_DTLS_OPTIONS ,
59+ [{protocol , dtls }]).
60+
5861-spec start_link (atom (), esockd :listen_on (), [esockd :option ()])
5962 -> {ok , pid ()} | ignore | {error , term ()}.
6063start_link (Proto , ListenOn , Opts ) ->
@@ -96,37 +99,41 @@ init({Proto, ListenOn, Opts}) ->
9699 Port = port (ListenOn ),
97100 process_flag (trap_exit , true ),
98101 esockd_server :ensure_stats ({Proto , ListenOn }),
99- SockOpts = merge_defaults (merge_addr (ListenOn , dltsopts (Opts ))),
102+ SockOpts = merge_sock_defaults (merge_addr (ListenOn , sockopts (Opts ))),
103+ DTLSOpts = merge_dtls_defaults (dtlsopts (Opts )),
100104 % % Don't active the socket...
101- case ssl :listen (Port , SockOpts ) of
105+ case ssl :listen (Port , SockOpts ++ DTLSOpts ) of
102106 % %case ssl:listen(Port, [{active, false} | proplists:delete(active, SockOpts)]) of
103107 {ok , LSock } ->
104108 {ok , {LAddr , LPort }} = ssl :sockname (LSock ),
105- % %error_logger:info_msg("~s listen on ~s:~p with ~p acceptors.~n",
106- % % [Proto, inet:ntoa(LAddr), LPort, AcceptorNum]),
107- {ok , # state {proto = Proto , listen_on = ListenOn , lsock = LSock ,
108- laddr = LAddr , lport = LPort , sockopts = SockOpts }};
109+ {ok , # state {proto = Proto , listen_on = ListenOn ,
110+ lsock = LSock , laddr = LAddr , lport = LPort ,
111+ sockopts = SockOpts , dtlsopts = DTLSOpts }};
109112 {error , Reason } ->
110113 error_logger :error_msg (" ~s failed to listen on ~p - ~p (~s )" ,
111114 [Proto , Port , Reason , inet :format_error (Reason )]),
112115 {stop , Reason }
113116 end .
114117
115- dltsopts (Opts ) ->
118+ dtlsopts (Opts ) ->
116119 % % Filter out `esockd:ssl_custom_option()`, otherwise DTLS listener will
117120 % % fail to start.
118- DTLSOpts = lists :foldl (
121+ lists :foldl (
119122 fun proplists :delete /2 ,
120123 proplists :get_value (dtls_options , Opts , []),
121124 [handshake_timeout , gc_after_handshake ]
122- ),
123- SockOpts = proplists :get_value (udp_options , Opts , []),
124- SockOpts ++ DTLSOpts .
125+ ).
126+
127+ sockopts (Opts ) ->
128+ proplists :get_value (udp_options , Opts , []).
125129
126130port (Port ) when is_integer (Port ) -> Port ;
127131port ({_Addr , Port }) -> Port .
128132
129- merge_defaults (SockOpts ) ->
133+ merge_sock_defaults (SockOpts ) ->
134+ esockd :merge_opts (? DEFAULT_SOCK_OPTIONS , SockOpts ).
135+
136+ merge_dtls_defaults (SockOpts ) ->
130137 esockd :merge_opts (? DEFAULT_DTLS_OPTIONS , SockOpts ).
131138
132139merge_addr (Port , SockOpts ) when is_integer (Port ) ->
@@ -143,17 +150,26 @@ handle_call(get_state, _From, State = #state{lsock = LSock, lport = LPort}) ->
143150 ],
144151 {reply , Reply , State };
145152
146- handle_call ({set_options , Opts }, _From , State = # state {lsock = LSock , sockopts = SockOpts }) ->
147- SockOptsIn = dltsopts (Opts ),
148- SockOptsChanged = esockd :changed_opts (SockOptsIn , SockOpts ),
149- case ssl :setopts (LSock , SockOptsChanged ) of
150- ok ->
151- SockOptsMerged = esockd :merge_opts (SockOpts , SockOptsChanged ),
152- {reply , ok , State # state {sockopts = SockOptsMerged }};
153- Error = {error , _ } ->
153+ handle_call ({set_options , Opts }
154+ , _From
155+ , State = # state {lsock = LSock , sockopts = SockOpts , dtlsopts = DTLSOpts }
156+ ) ->
157+ SockOptsIn = sockopts (Opts ),
158+ DTLSOptsIn = dtlsopts (Opts ),
159+ case esockd :changed_opts (DTLSOptsIn , DTLSOpts ) of
160+ [] ->
161+ SockOptsChanged = esockd :changed_opts (SockOptsIn , SockOpts ),
162+ case ssl :setopts (LSock , SockOptsChanged ) of
163+ ok ->
164+ {reply , ok , State # state {sockopts = SockOptsIn }};
165+ Error = {error , _ } ->
166+ {reply , Error , State }
167+ end ;
168+ [_ | _ ] ->
169+ % % If the dTLS option set is different, bail out.
154170 % % Setting dTLS options on listening socket always succeeds,
155171 % % even if the options are invalid.
156- {reply , Error , State }
172+ {reply , { error , not_supported } , State }
157173 end ;
158174
159175handle_call (Req , _From , State ) ->
0 commit comments