summaryrefslogtreecommitdiff
path: root/components/dlink_tls/src/dlink_tls_listener.erl
blob: 0effc66591ab26c40572142181329e677a5fee23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil -*-
%%
%% Copyright (C) 2014, Jaguar Land Rover
%%
%% This program is licensed under the terms and conditions of the
%% Mozilla Public License, version 2.0.  The full text of the
%% Mozilla Public License is at https://www.mozilla.org/MPL/2.0/
%%

%% Setup a listen socket and manage connections to remote parties.
%% Can also retrieve connections by peer address.
-module(dlink_tls_listener).

-include_lib("lager/include/log.hrl").

-export([start_link/0,
         add_listener/4,
         remove_listener/3]).

-export([init/2, handle_call/3, handle_cast/2, handle_info/2]).
-export([terminate/2, sock_opts/0, new_connection/4]).

-behavior(gen_nb_server).

start_link() ->
    gen_nb_server:start_link(?MODULE, []).

add_listener(Pid, IpAddr, Port, CompSpec) ->
    gen_server:call(Pid, {add_listener, IpAddr, Port, CompSpec}).

remove_listener(Pid, IpAddr, Port) ->
    gen_server:call(Pid, {remove_listener, IpAddr, Port}).

init([], State) ->
    {ok, State}.

handle_call({add_listener, IpAddr, Port, CompSpec}, _From, State) ->
    case gen_nb_server:add_listen_socket({IpAddr, Port}, State) of
        {ok, State1} ->
            {reply, ok, gen_nb_server:store_cb_state( CompSpec, State1 )};

        Error ->
            {reply, Error, gen_nb_server:store_cb_state( CompSpec, State )}
    end;

handle_call({remove_listener, IpAddr, Port}, _From, State) ->
    case gen_nb_server:remove_listen_socket({IpAddr, Port}, State) of
        {ok, State1} ->
            {reply, ok, State1};
        Error ->
            {reply, Error, State}
    end;

handle_call(_Msg, _From, State) ->
    {reply, ignored, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Msg, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

sock_opts() ->
    [{mode, binary}, {active, once}, {packet, 0}].

new_connection(IP, Port, Sock, State) ->
    ?debug("new_connection(): Peer IP:    ~p (ignored)", [IP]),
    ?debug("new_connection(): Peer Port:  ~p (ignored)", [Port]),
    ?debug("new_connection(): Sock:       ~p", [Sock]),

    %% IP and Port are garbage. We'll grab peername when we get our
    %% first data.
    %% Provide component spec as extra arg.
    CompSpec = gen_nb_server:get_cb_state(State),
    {ok, P} = dlink_tls_conn:setup(
                undefined, 0, Sock,
                dlink_tls_rpc,
                handle_socket, CompSpec),
    dlink_tls_conn:upgrade(P, server, CompSpec),
    {ok, State}.