Handle HAVE_ALL and HAVE_NONE. Cleanup the BITFIELD message.
[etorrent.git] / lib / etorrent-1.0 / src / etorrent_listener.erl
blob10b3f4fe731013148b3b7639cf62725b30b6ad9d
1 %%%-------------------------------------------------------------------
2 %%% File : listener.erl
3 %%% Author : Jesper Louis Andersen <jesper.louis.andersen@gmail.com>
4 %%% License : See COPYING
5 %%% Description : Listen for incoming connections
6 %%%
7 %%% Created : 30 Jul 2007 by Jesper Louis Andersen <jesper.louis.andersen@gmail.com>
8 %%%-------------------------------------------------------------------
9 -module(etorrent_listener).
11 -behaviour(gen_server).
13 %% API
14 -export([start_link/0, get_socket/0]).
16 %% gen_server callbacks
17 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
18 terminate/2, code_change/3]).
20 -record(state, { listen_socket = none}).
22 -define(SERVER, ?MODULE).
23 -define(DEFAULT_SOCKET_INCREASE, 10).
26 %%====================================================================
27 %% API
28 %%====================================================================
29 %%--------------------------------------------------------------------
30 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
31 %% Description: Starts the server
32 %%--------------------------------------------------------------------
33 start_link() ->
34 gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
36 %%--------------------------------------------------------------------
37 %% Function: get_socket() -> listen_socket()
38 %% Description: Return the listen socket we are bound to.
39 %%--------------------------------------------------------------------
40 get_socket() ->
41 gen_server:call(?SERVER, get_socket).
43 %%====================================================================
44 %% gen_server callbacks
45 %%====================================================================
47 %%--------------------------------------------------------------------
48 %% Function: init(Args) -> {ok, State} |
49 %% {ok, State, Timeout} |
50 %% ignore |
51 %% {stop, Reason}
52 %% Description: Initiates the server
53 %%--------------------------------------------------------------------
54 init([]) ->
55 {ok, Port} = application:get_env(etorrent, port),
56 {ok, ListenSocket} = find_listen_socket(Port, ?DEFAULT_SOCKET_INCREASE),
57 {ok, #state{ listen_socket = ListenSocket}}.
59 %%--------------------------------------------------------------------
60 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
61 %% {reply, Reply, State, Timeout} |
62 %% {noreply, State} |
63 %% {noreply, State, Timeout} |
64 %% {stop, Reason, Reply, State} |
65 %% {stop, Reason, State}
66 %% Description: Handling call messages
67 %%--------------------------------------------------------------------
68 handle_call(get_socket, _From, S) ->
69 {reply, {ok, S#state.listen_socket}, S};
70 handle_call(_Request, _From, State) ->
71 Reply = ok,
72 {reply, Reply, State}.
74 %%--------------------------------------------------------------------
75 %% Function: handle_cast(Msg, State) -> {noreply, State} |
76 %% {noreply, State, Timeout} |
77 %% {stop, Reason, State}
78 %% Description: Handling cast messages
79 %%--------------------------------------------------------------------
80 handle_cast(_Msg, State) ->
81 {noreply, State}.
83 %%--------------------------------------------------------------------
84 %% Function: handle_info(Info, State) -> {noreply, State} |
85 %% {noreply, State, Timeout} |
86 %% {stop, Reason, State}
87 %% Description: Handling all non call/cast messages
88 %%--------------------------------------------------------------------
89 handle_info(_Info, State) ->
90 {noreply, State}.
92 %%--------------------------------------------------------------------
93 %% Function: terminate(Reason, State) -> void()
94 %% Description: This function is called by a gen_server when it is about to
95 %% terminate. It should be the opposite of Module:init/1 and do any necessary
96 %% cleaning up. When it returns, the gen_server terminates with Reason.
97 %% The return value is ignored.
98 %%--------------------------------------------------------------------
99 terminate(_Reason, State) ->
100 % Explicitly close the socket if we terminate.
101 error_logger:info_report([listener_closing_socket]),
102 gen_tcp:close(State#state.listen_socket),
105 %%--------------------------------------------------------------------
106 %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
107 %% Description: Convert process state when code is changed
108 %%--------------------------------------------------------------------
109 code_change(_OldVsn, State, _Extra) ->
110 {ok, State}.
112 %%--------------------------------------------------------------------
113 %%% Internal functions
114 %%--------------------------------------------------------------------
115 find_listen_socket(_Port, 0) ->
116 {error, could_not_find_free_socket};
117 find_listen_socket(Port, N) ->
118 case gen_tcp:listen(Port, [binary, inet, {active, false}]) of
119 {ok, Socket} ->
120 {ok, Socket};
121 {error, eaddrinuse} ->
122 find_listen_socket(Port+1, N-1)
123 end.