From 4d8f7706240a1603468968f47fc7b150b788d62f Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 8 Apr 2013 11:12:54 +0200 Subject: Switch to rebar build tool Use dynamic Rebar configuration Make iconv dependency optional Disable transient_supervisors compile option Add hipe compilation support Only compile ibrowse and lhttpc when needed Make it possible to generate an OTP application release Add --enable-debug compile option Add --enable-all compiler option Add --enable-tools configure option Add --with-erlang configure option. Add --enable-erlang-version-check configure option. Add lager support Improve the test suite --- src/mod_proxy65/Makefile.in | 38 ----- src/mod_proxy65/Makefile.win32 | 27 --- src/mod_proxy65/mod_proxy65.erl | 82 --------- src/mod_proxy65/mod_proxy65.hrl | 74 -------- src/mod_proxy65/mod_proxy65_lib.erl | 73 -------- src/mod_proxy65/mod_proxy65_service.erl | 285 ------------------------------- src/mod_proxy65/mod_proxy65_sm.erl | 174 ------------------- src/mod_proxy65/mod_proxy65_stream.erl | 287 -------------------------------- 8 files changed, 1040 deletions(-) delete mode 100644 src/mod_proxy65/Makefile.in delete mode 100644 src/mod_proxy65/Makefile.win32 delete mode 100644 src/mod_proxy65/mod_proxy65.erl delete mode 100644 src/mod_proxy65/mod_proxy65.hrl delete mode 100644 src/mod_proxy65/mod_proxy65_lib.erl delete mode 100644 src/mod_proxy65/mod_proxy65_service.erl delete mode 100644 src/mod_proxy65/mod_proxy65_sm.erl delete mode 100644 src/mod_proxy65/mod_proxy65_stream.erl (limited to 'src/mod_proxy65') diff --git a/src/mod_proxy65/Makefile.in b/src/mod_proxy65/Makefile.in deleted file mode 100644 index 3fc94c662..000000000 --- a/src/mod_proxy65/Makefile.in +++ /dev/null @@ -1,38 +0,0 @@ -# $Id$ - -CC = @CC@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -ERLANG_CFLAGS = @ERLANG_CFLAGS@ -ERLANG_LIBS = @ERLANG_LIBS@ - -EFLAGS += -I .. -EFLAGS += -pz .. - -# make debug=true to compile Erlang module with debug informations. -ifdef debug - EFLAGS+=+debug_info -endif - -OUTDIR = .. -SOURCES = $(wildcard *.erl) -BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) - - -all: $(BEAMS) - -$(OUTDIR)/%.beam: %.erl - @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< - -clean: - rm -f $(BEAMS) - -distclean: clean - rm -f Makefile - -TAGS: - etags *.erl - diff --git a/src/mod_proxy65/Makefile.win32 b/src/mod_proxy65/Makefile.win32 deleted file mode 100644 index 7683097d3..000000000 --- a/src/mod_proxy65/Makefile.win32 +++ /dev/null @@ -1,27 +0,0 @@ - -include ..\Makefile.inc - -EFLAGS = -I .. -pz .. - -OUTDIR = .. -BEAMS = ..\mod_proxy65.beam ..\mod_proxy65_lib.beam ..\mod_proxy65_service.beam ..\mod_proxy65_sm.beam ..\mod_proxy65_stream.beam - -ALL : $(BEAMS) - -CLEAN : - -@erase $(BEAMS) - -$(OUTDIR)\mod_proxy65.beam : mod_proxy65.erl - erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65.erl - -$(OUTDIR)\mod_proxy65_service.beam : mod_proxy65_service.erl - erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_service.erl - -$(OUTDIR)\mod_proxy65_sm.beam : mod_proxy65_sm.erl - erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_sm.erl - -$(OUTDIR)\mod_proxy65_stream.beam : mod_proxy65_stream.erl - erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_stream.erl - -$(OUTDIR)\mod_proxy65_lib.beam : mod_proxy65_lib.erl - erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_lib.erl diff --git a/src/mod_proxy65/mod_proxy65.erl b/src/mod_proxy65/mod_proxy65.erl deleted file mode 100644 index 3e8354caf..000000000 --- a/src/mod_proxy65/mod_proxy65.erl +++ /dev/null @@ -1,82 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_proxy65.erl -%%% Author : Evgeniy Khramtsov -%%% Purpose : Main supervisor. -%%% Created : 12 Oct 2006 by Evgeniy Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - --module(mod_proxy65). - --author('xram@jabber.ru'). - --behaviour(gen_mod). - --behaviour(supervisor). - -%% gen_mod callbacks. --export([start/2, stop/1]). - -%% supervisor callbacks. --export([init/1]). - -%% API. --export([start_link/2]). - --define(PROCNAME, ejabberd_mod_proxy65). - -start(Host, Opts) -> - case mod_proxy65_service:add_listener(Host, Opts) of - {error, _} = Err -> erlang:error(Err); - _ -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, - transient, infinity, supervisor, [?MODULE]}, - supervisor:start_child(ejabberd_sup, ChildSpec) - end. - -stop(Host) -> - mod_proxy65_service:delete_listener(Host), - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - supervisor:terminate_child(ejabberd_sup, Proc), - supervisor:delete_child(ejabberd_sup, Proc). - -start_link(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - supervisor:start_link({local, Proc}, ?MODULE, - [Host, Opts]). - -init([Host, Opts]) -> - Service = {mod_proxy65_service, - {mod_proxy65_service, start_link, [Host, Opts]}, - transient, 5000, worker, [mod_proxy65_service]}, - StreamSupervisor = {ejabberd_mod_proxy65_sup, - {ejabberd_tmp_sup, start_link, - [gen_mod:get_module_proc(Host, - ejabberd_mod_proxy65_sup), - mod_proxy65_stream]}, - transient, infinity, supervisor, [ejabberd_tmp_sup]}, - StreamManager = {mod_proxy65_sm, - {mod_proxy65_sm, start_link, [Host, Opts]}, transient, - 5000, worker, [mod_proxy65_sm]}, - {ok, - {{one_for_one, 10, 1}, - [StreamManager, StreamSupervisor, Service]}}. diff --git a/src/mod_proxy65/mod_proxy65.hrl b/src/mod_proxy65/mod_proxy65.hrl deleted file mode 100644 index d0779af14..000000000 --- a/src/mod_proxy65/mod_proxy65.hrl +++ /dev/null @@ -1,74 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% RFC 1928 constants. -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - -%% Version --define(VERSION_5, 5). - -%% Authentication methods --define(AUTH_ANONYMOUS, 0). - --define(AUTH_GSSAPI, 1). - --define(AUTH_PLAIN, 2). - -%% Address Type --define(AUTH_NO_METHODS, 255). - --define(ATYP_IPV4, 1). - --define(ATYP_DOMAINNAME, 3). - --define(ATYP_IPV6, 4). - -%% Commands --define(CMD_CONNECT, 1). - --define(CMD_BIND, 2). - --define(CMD_UDP, 3). - -%% RFC 1928 replies --define(SUCCESS, 0). - --define(ERR_GENERAL_FAILURE, 1). - --define(ERR_NOT_ALLOWED, 2). - --define(ERR_NETWORK_UNREACHABLE, 3). - --define(ERR_HOST_UNREACHABLE, 4). - --define(ERR_CONNECTION_REFUSED, 5). - --define(ERR_TTL_EXPIRED, 6). - --define(ERR_COMMAND_NOT_SUPPORTED, 7). - --define(ERR_ADDRESS_TYPE_NOT_SUPPORTED, 8). - -%% RFC 1928 defined timeout. --define(SOCKS5_REPLY_TIMEOUT, 10000). - --record(s5_request, {rsv = 0 :: integer(), - cmd = connect :: connect | udp, - sha1 = <<"">> :: binary()}). diff --git a/src/mod_proxy65/mod_proxy65_lib.erl b/src/mod_proxy65/mod_proxy65_lib.erl deleted file mode 100644 index 388811436..000000000 --- a/src/mod_proxy65/mod_proxy65_lib.erl +++ /dev/null @@ -1,73 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_proxy65_lib.erl -%%% Author : Evgeniy Khramtsov -%%% Purpose : SOCKS5 parsing library. -%%% Created : 12 Oct 2006 by Evgeniy Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - --module(mod_proxy65_lib). - --author('xram@jabber.ru'). - --include("mod_proxy65.hrl"). - --export([unpack_init_message/1, unpack_auth_request/1, - unpack_request/1, make_init_reply/1, make_auth_reply/1, - make_reply/1, make_error_reply/1, make_error_reply/2]). - -unpack_init_message(<<(?VERSION_5), N, - AuthMethodList:N/binary>>) - when N > 0, N < 256 -> - {ok, binary_to_list(AuthMethodList)}; -unpack_init_message(_) -> error. - -unpack_auth_request(<<1, ULen, User:ULen/binary, PLen, - Pass:PLen/binary>>) - when ULen < 256, PLen < 256 -> - {(User), (Pass)}; -unpack_auth_request(_) -> error. - -unpack_request(<<(?VERSION_5), CMD, RSV, - (?ATYP_DOMAINNAME), 40, SHA1:40/binary, 0, 0>>) - when CMD == (?CMD_CONNECT); CMD == (?CMD_UDP) -> - Command = if CMD == (?CMD_CONNECT) -> connect; - CMD == (?CMD_UDP) -> udp - end, - #s5_request{cmd = Command, rsv = RSV, sha1 = (SHA1)}; -unpack_request(_) -> error. - -make_init_reply(Method) -> [?VERSION_5, Method]. - -make_auth_reply(true) -> [1, ?SUCCESS]; -make_auth_reply(false) -> [1, ?ERR_NOT_ALLOWED]. - -make_reply(#s5_request{rsv = RSV, sha1 = SHA1}) -> - [?VERSION_5, ?SUCCESS, RSV, ?ATYP_DOMAINNAME, - byte_size(SHA1), SHA1, 0, 0]. - -make_error_reply(Request) -> - make_error_reply(Request, ?ERR_NOT_ALLOWED). - -make_error_reply(#s5_request{rsv = RSV, sha1 = SHA1}, - Reason) -> - [?VERSION_5, Reason, RSV, ?ATYP_DOMAINNAME, - byte_size(SHA1), SHA1, 0, 0]. diff --git a/src/mod_proxy65/mod_proxy65_service.erl b/src/mod_proxy65/mod_proxy65_service.erl deleted file mode 100644 index 22ac6cde6..000000000 --- a/src/mod_proxy65/mod_proxy65_service.erl +++ /dev/null @@ -1,285 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_proxy65_service.erl -%%% Author : Evgeniy Khramtsov -%%% Purpose : SOCKS5 Bytestreams XMPP service. -%%% Created : 12 Oct 2006 by Evgeniy Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - --module(mod_proxy65_service). - --author('xram@jabber.ru'). - --behaviour(gen_server). - -%% gen_server callbacks. --export([init/1, handle_info/2, handle_call/3, - handle_cast/2, terminate/2, code_change/3]). - -%% API. --export([start_link/2, add_listener/2, - delete_listener/1]). - --include("ejabberd.hrl"). - --include("jlib.hrl"). - --define(PROCNAME, ejabberd_mod_proxy65_service). - --record(state, - {myhost = <<"">> :: binary(), - serverhost = <<"">> :: binary(), - name = <<"">> :: binary(), - stream_addr = [] :: [attr()], - port = 0 :: inet:port_number(), - ip = {127,0,0,1} :: inet:ip_address(), - acl = none :: atom()}). - -%%%------------------------ -%%% gen_server callbacks -%%%------------------------ - -start_link(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:start_link({local, Proc}, ?MODULE, - [Host, Opts], []). - -init([Host, Opts]) -> - State = parse_options(Host, Opts), - ejabberd_router:register_route(State#state.myhost), - {ok, State}. - -terminate(_Reason, #state{myhost = MyHost}) -> - ejabberd_router:unregister_route(MyHost), ok. - -handle_info({route, From, To, - #xmlel{name = <<"iq">>} = Packet}, - State) -> - IQ = jlib:iq_query_info(Packet), - case catch process_iq(From, IQ, State) of - Result when is_record(Result, iq) -> - ejabberd_router:route(To, From, jlib:iq_to_xml(Result)); - {'EXIT', Reason} -> - ?ERROR_MSG("Error when processing IQ stanza: ~p", - [Reason]), - Err = jlib:make_error_reply(Packet, - ?ERR_INTERNAL_SERVER_ERROR), - ejabberd_router:route(To, From, Err); - _ -> ok - end, - {noreply, State}; -handle_info(_Info, State) -> {noreply, State}. - -handle_call(get_port_ip, _From, State) -> - {reply, {port_ip, State#state.port, State#state.ip}, - State}; -handle_call(_Request, _From, State) -> - {reply, ok, State}. - -handle_cast(_Request, State) -> {noreply, State}. - -code_change(_OldVsn, State, _Extra) -> {ok, State}. - -%%%------------------------ -%%% Listener management -%%%------------------------ - -add_listener(Host, Opts) -> - State = parse_options(Host, Opts), - NewOpts = [Host | Opts], - ejabberd_listener:add_listener({State#state.port, - State#state.ip}, - mod_proxy65_stream, NewOpts). - -delete_listener(Host) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - {port_ip, Port, IP} = gen_server:call(Proc, - get_port_ip), - catch ejabberd_listener:delete_listener({Port, IP}, - mod_proxy65_stream). - -%%%------------------------ -%%% IQ Processing -%%%------------------------ - -%% disco#info request -process_iq(_, - #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = - IQ, - #state{name = Name, serverhost = ServerHost}) -> - Info = ejabberd_hooks:run_fold(disco_info, ServerHost, - [], [ServerHost, ?MODULE, <<"">>, <<"">>]), - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_INFO}], - children = iq_disco_info(Lang, Name) ++ Info}]}; -%% disco#items request -process_iq(_, - #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}], - children = []}]}; -%% vCard request -process_iq(_, - #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ, - _) -> - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"vCard">>, - attrs = [{<<"xmlns">>, ?NS_VCARD}], - children = iq_vcard(Lang)}]}; -%% bytestreams info request -process_iq(JID, - #iq{type = get, sub_el = SubEl, - xmlns = ?NS_BYTESTREAMS} = - IQ, - #state{acl = ACL, stream_addr = StreamAddr, - serverhost = ServerHost}) -> - case acl:match_rule(ServerHost, ACL, JID) of - allow -> - StreamHostEl = [#xmlel{name = <<"streamhost">>, - attrs = StreamAddr, children = []}], - IQ#iq{type = result, - sub_el = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_BYTESTREAMS}], - children = StreamHostEl}]}; - deny -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} - end; -%% bytestream activation request -process_iq(InitiatorJID, - #iq{type = set, sub_el = SubEl, - xmlns = ?NS_BYTESTREAMS} = - IQ, - #state{acl = ACL, serverhost = ServerHost}) -> - case acl:match_rule(ServerHost, ACL, InitiatorJID) of - allow -> - ActivateEl = xml:get_path_s(SubEl, - [{elem, <<"activate">>}]), - SID = xml:get_tag_attr_s(<<"sid">>, SubEl), - case catch - jlib:string_to_jid(xml:get_tag_cdata(ActivateEl)) - of - TargetJID - when is_record(TargetJID, jid), SID /= <<"">>, - byte_size(SID) =< 128, TargetJID /= InitiatorJID -> - Target = - jlib:jid_to_string(jlib:jid_tolower(TargetJID)), - Initiator = - jlib:jid_to_string(jlib:jid_tolower(InitiatorJID)), - SHA1 = sha:sha(<>), - case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID, - TargetJID, ServerHost) - of - ok -> IQ#iq{type = result, sub_el = []}; - false -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; - limit -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_RESOURCE_CONSTRAINT]}; - conflict -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_CONFLICT]}; - _ -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} - end; - _ -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} - end; - deny -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} - end; -%% Unknown "set" or "get" request -process_iq(_, #iq{type = Type, sub_el = SubEl} = IQ, _) - when Type == get; Type == set -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; -%% IQ "result" or "error". -process_iq(_, _, _) -> ok. - -%%%------------------------- -%%% Auxiliary functions. -%%%------------------------- --define(FEATURE(Feat), - #xmlel{name = <<"feature">>, - attrs = [{<<"var">>, Feat}], children = []}). - -iq_disco_info(Lang, Name) -> - [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"proxy">>}, - {<<"type">>, <<"bytestreams">>}, - {<<"name">>, translate:translate(Lang, Name)}], - children = []}, - ?FEATURE((?NS_DISCO_INFO)), ?FEATURE((?NS_VCARD)), - ?FEATURE((?NS_BYTESTREAMS))]. - -iq_vcard(Lang) -> - [#xmlel{name = <<"FN">>, attrs = [], - children = [{xmlcdata, <<"ejabberd/mod_proxy65">>}]}, - #xmlel{name = <<"URL">>, attrs = [], - children = [{xmlcdata, ?EJABBERD_URI}]}, - #xmlel{name = <<"DESC">>, attrs = [], - children = - [{xmlcdata, - <<(translate:translate(Lang, - <<"ejabberd SOCKS5 Bytestreams module">>))/binary, - "\nCopyright (c) 2003-2013 ProcessOne">>}]}]. - -parse_options(ServerHost, Opts) -> - MyHost = gen_mod:get_opt_host(ServerHost, Opts, - <<"proxy.@HOST@">>), - Port = gen_mod:get_opt(port, Opts, - fun(P) when is_integer(P), P>0, P<65536 -> P end, - 7777), - ACL = gen_mod:get_opt(access, Opts, fun(A) when is_atom(A) -> A end, - all), - Name = gen_mod:get_opt(name, Opts, fun iolist_to_binary/1, - <<"SOCKS5 Bytestreams">>), - IP = gen_mod:get_opt(ip, Opts, - fun(Addr) -> - jlib:ip_to_list(Addr), - Addr - end, get_my_ip()), - HostName = gen_mod:get_opt(hostname, Opts, - fun(Addr) when is_tuple(Addr) -> - jlib:ip_to_list(Addr); - (S) -> - iolist_to_binary(S) - end, jlib:ip_to_list(IP)), - StreamAddr = [{<<"jid">>, MyHost}, - {<<"host">>, HostName}, - {<<"port">>, jlib:integer_to_binary(Port)}], - #state{myhost = MyHost, serverhost = ServerHost, - name = Name, port = Port, ip = IP, - stream_addr = StreamAddr, acl = ACL}. - -get_my_ip() -> - {ok, MyHostName} = inet:gethostname(), - case inet:getaddr(MyHostName, inet) of - {ok, Addr} -> Addr; - {error, _} -> {127, 0, 0, 1} - end. diff --git a/src/mod_proxy65/mod_proxy65_sm.erl b/src/mod_proxy65/mod_proxy65_sm.erl deleted file mode 100644 index fa9d257ef..000000000 --- a/src/mod_proxy65/mod_proxy65_sm.erl +++ /dev/null @@ -1,174 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_proxy65_sm.erl -%%% Author : Evgeniy Khramtsov -%%% Purpose : Bytestreams manager. -%%% Created : 12 Oct 2006 by Evgeniy Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - --module(mod_proxy65_sm). - --author('xram@jabber.ru'). - --behaviour(gen_server). - -%% gen_server callbacks. --export([init/1, handle_info/2, handle_call/3, - handle_cast/2, terminate/2, code_change/3]). - -%% API. --export([start_link/2, register_stream/1, - unregister_stream/1, activate_stream/4]). - --record(state, {max_connections = infinity :: non_neg_integer() | infinity}). - --include("jlib.hrl"). - --record(bytestream, - {sha1 = <<"">> :: binary() | '$1', - target :: pid() | '_', - initiator :: pid() | '_', - active = false :: boolean() | '_', - jid_i = {<<"">>, <<"">>, <<"">>} :: ljid() | '_'}). - --define(PROCNAME, ejabberd_mod_proxy65_sm). - -%% Unused callbacks. -handle_cast(_Request, State) -> {noreply, State}. - -code_change(_OldVsn, State, _Extra) -> {ok, State}. - -handle_info(_Info, State) -> {noreply, State}. - -%%---------------- - -start_link(Host, Opts) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - gen_server:start_link({local, Proc}, ?MODULE, [Opts], - []). - -init([Opts]) -> - mnesia:create_table(bytestream, [{ram_copies, [node()]}, - {attributes, record_info(fields, bytestream)}]), - mnesia:add_table_copy(bytestream, node(), ram_copies), - MaxConnections = gen_mod:get_opt(max_connections, Opts, - fun(I) when is_integer(I), I>0 -> - I; - (infinity) -> - infinity - end, infinity), - {ok, #state{max_connections = MaxConnections}}. - -terminate(_Reason, _State) -> ok. - -handle_call({activate, SHA1, IJid}, _From, State) -> - MaxConns = State#state.max_connections, - F = fun () -> - case mnesia:read(bytestream, SHA1, write) of - [#bytestream{target = TPid, initiator = IPid} = - ByteStream] - when is_pid(TPid), is_pid(IPid) -> - ActiveFlag = ByteStream#bytestream.active, - if ActiveFlag == false -> - ConnsPerJID = mnesia:select(bytestream, - [{#bytestream{sha1 = - '$1', - jid_i = - IJid, - _ = '_'}, - [], ['$1']}]), - if length(ConnsPerJID) < MaxConns -> - mnesia:write(ByteStream#bytestream{active = - true, - jid_i = - IJid}), - {ok, IPid, TPid}; - true -> {limit, IPid, TPid} - end; - true -> conflict - end; - _ -> false - end - end, - Reply = mnesia:transaction(F), - {reply, Reply, State}; -handle_call(_Request, _From, State) -> - {reply, ok, State}. - -%%%---------------------- -%%% API. -%%%---------------------- -%%%--------------------------------------------------- -%%% register_stream(SHA1) -> {atomic, ok} | -%%% {atomic, error} | -%%% transaction abort -%%% SHA1 = string() -%%%--------------------------------------------------- -register_stream(SHA1) when is_binary(SHA1) -> - StreamPid = self(), - F = fun () -> - case mnesia:read(bytestream, SHA1, write) of - [] -> - mnesia:write(#bytestream{sha1 = SHA1, - target = StreamPid}); - [#bytestream{target = Pid, initiator = undefined} = - ByteStream] - when is_pid(Pid), Pid /= StreamPid -> - mnesia:write(ByteStream#bytestream{initiator = - StreamPid}); - _ -> error - end - end, - mnesia:transaction(F). - -%%%---------------------------------------------------- -%%% unregister_stream(SHA1) -> ok | transaction abort -%%% SHA1 = string() -%%%---------------------------------------------------- -unregister_stream(SHA1) when is_binary(SHA1) -> - F = fun () -> mnesia:delete({bytestream, SHA1}) end, - mnesia:transaction(F). - -%%%-------------------------------------------------------- -%%% activate_stream(SHA1, IJid, TJid, Host) -> ok | -%%% false | -%%% limit | -%%% conflict | -%%% error -%%% SHA1 = string() -%%% IJid = TJid = jid() -%%% Host = string() -%%%-------------------------------------------------------- -activate_stream(SHA1, IJid, TJid, Host) - when is_binary(SHA1) -> - Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - case catch gen_server:call(Proc, {activate, SHA1, IJid}) - of - {atomic, {ok, IPid, TPid}} -> - mod_proxy65_stream:activate({IPid, IJid}, {TPid, TJid}); - {atomic, {limit, IPid, TPid}} -> - mod_proxy65_stream:stop(IPid), - mod_proxy65_stream:stop(TPid), - limit; - {atomic, conflict} -> conflict; - {atomic, false} -> false; - _ -> error - end. diff --git a/src/mod_proxy65/mod_proxy65_stream.erl b/src/mod_proxy65/mod_proxy65_stream.erl deleted file mode 100644 index 1eca99b39..000000000 --- a/src/mod_proxy65/mod_proxy65_stream.erl +++ /dev/null @@ -1,287 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : mod_proxy65_stream.erl -%%% Author : Evgeniy Khramtsov -%%% Purpose : Bytestream process. -%%% Created : 12 Oct 2006 by Evgeniy Khramtsov -%%% -%%% ejabberd, Copyright (C) 2002-2013 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License -%%% along with this program; if not, write to the Free Software -%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -%%% 02111-1307 USA -%%% -%%%---------------------------------------------------------------------- - --module(mod_proxy65_stream). - --author('xram@jabber.ru'). - --behaviour(gen_fsm). - -%% gen_fsm callbacks. --export([init/1, handle_event/3, handle_sync_event/4, - code_change/4, handle_info/3, terminate/3]). - -%% gen_fsm states. --export([wait_for_init/2, wait_for_auth/2, - wait_for_request/2, wait_for_activation/2, - stream_established/2]). - -%% API. --export([start/2, stop/1, start_link/3, activate/2, - relay/3, socket_type/0]). - --include("mod_proxy65.hrl"). - --include("ejabberd.hrl"). - --define(WAIT_TIMEOUT, 60000). - --record(state, - {socket :: inet:socket(), - timer = make_ref() :: reference(), - sha1 = <<"">> :: binary(), - host = <<"">> :: binary(), - auth_type = anonymous :: plain | anonymous, - shaper = none :: shaper:shaper()}). - -%% Unused callbacks -handle_event(_Event, StateName, StateData) -> - {next_state, StateName, StateData}. - -code_change(_OldVsn, StateName, StateData, _Extra) -> - {ok, StateName, StateData}. - -%%------------------------------- - -start({gen_tcp, Socket}, Opts1) -> - {[Host], Opts} = lists:partition(fun (O) -> is_binary(O) - end, - Opts1), - Supervisor = gen_mod:get_module_proc(Host, - ejabberd_mod_proxy65_sup), - supervisor:start_child(Supervisor, - [Socket, Host, Opts]). - -start_link(Socket, Host, Opts) -> - gen_fsm:start_link(?MODULE, [Socket, Host, Opts], []). - -init([Socket, Host, Opts]) -> - process_flag(trap_exit, true), - AuthType = gen_mod:get_opt(auth_type, Opts, - fun(plain) -> plain; - (anonymous) -> anonymous - end, anonymous), - Shaper = gen_mod:get_opt(shaper, Opts, - fun(A) when is_atom(A) -> A end, - none), - RecvBuf = gen_mod:get_opt(recbuf, Opts, - fun(I) when is_integer(I), I>0 -> I end, - 8192), - SendBuf = gen_mod:get_opt(sndbuf, Opts, - fun(I) when is_integer(I), I>0 -> I end, - 8192), - TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), - inet:setopts(Socket, - [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]), - {ok, wait_for_init, - #state{host = Host, auth_type = AuthType, - socket = Socket, shaper = Shaper, timer = TRef}}. - -terminate(_Reason, StateName, #state{sha1 = SHA1}) -> - catch mod_proxy65_sm:unregister_stream(SHA1), - if StateName == stream_established -> - ?INFO_MSG("Bytestream terminated", []); - true -> ok - end. - -%%%------------------------------ -%%% API. -%%%------------------------------ -socket_type() -> raw. - -stop(StreamPid) -> StreamPid ! stop. - -activate({P1, J1}, {P2, J2}) -> - case catch {gen_fsm:sync_send_all_state_event(P1, - get_socket), - gen_fsm:sync_send_all_state_event(P2, get_socket)} - of - {S1, S2} when is_port(S1), is_port(S2) -> - P1 ! {activate, P2, S2, J1, J2}, - P2 ! {activate, P1, S1, J1, J2}, - JID1 = jlib:jid_to_string(J1), - JID2 = jlib:jid_to_string(J2), - ?INFO_MSG("(~w:~w) Activated bytestream for ~s " - "-> ~s", - [P1, P2, JID1, JID2]), - ok; - _ -> error - end. - -%%%----------------------- -%%% States -%%%----------------------- -wait_for_init(Packet, - #state{socket = Socket, auth_type = AuthType} = - StateData) -> - case mod_proxy65_lib:unpack_init_message(Packet) of - {ok, AuthMethods} -> - Method = select_auth_method(AuthType, AuthMethods), - gen_tcp:send(Socket, - mod_proxy65_lib:make_init_reply(Method)), - case Method of - ?AUTH_ANONYMOUS -> - {next_state, wait_for_request, StateData}; - ?AUTH_PLAIN -> {next_state, wait_for_auth, StateData}; - ?AUTH_NO_METHODS -> {stop, normal, StateData} - end; - error -> {stop, normal, StateData} - end. - -wait_for_auth(Packet, - #state{socket = Socket, host = Host} = StateData) -> - case mod_proxy65_lib:unpack_auth_request(Packet) of - {User, Pass} -> - Result = ejabberd_auth:check_password(User, Host, Pass), - gen_tcp:send(Socket, - mod_proxy65_lib:make_auth_reply(Result)), - case Result of - true -> {next_state, wait_for_request, StateData}; - false -> {stop, normal, StateData} - end; - _ -> {stop, normal, StateData} - end. - -wait_for_request(Packet, - #state{socket = Socket} = StateData) -> - Request = mod_proxy65_lib:unpack_request(Packet), - case Request of - #s5_request{sha1 = SHA1, cmd = connect} -> - case catch mod_proxy65_sm:register_stream(SHA1) of - {atomic, ok} -> - inet:setopts(Socket, [{active, false}]), - gen_tcp:send(Socket, - mod_proxy65_lib:make_reply(Request)), - {next_state, wait_for_activation, - StateData#state{sha1 = SHA1}}; - _ -> - Err = mod_proxy65_lib:make_error_reply(Request), - gen_tcp:send(Socket, Err), - {stop, normal, StateData} - end; - #s5_request{cmd = udp} -> - Err = mod_proxy65_lib:make_error_reply(Request, - ?ERR_COMMAND_NOT_SUPPORTED), - gen_tcp:send(Socket, Err), - {stop, normal, StateData}; - _ -> {stop, normal, StateData} - end. - -wait_for_activation(_Data, StateData) -> - {next_state, wait_for_activation, StateData}. - -stream_established(_Data, StateData) -> - {next_state, stream_established, StateData}. - -%%%----------------------- -%%% Callbacks processing -%%%----------------------- - -%% SOCKS5 packets. -handle_info({tcp, _S, Data}, StateName, StateData) - when StateName /= wait_for_activation -> - erlang:cancel_timer(StateData#state.timer), - TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), - gen_fsm:send_event(self(), Data), - {next_state, StateName, StateData#state{timer = TRef}}; -%% Activation message. -handle_info({activate, PeerPid, PeerSocket, IJid, TJid}, - wait_for_activation, StateData) -> - erlang:monitor(process, PeerPid), - erlang:cancel_timer(StateData#state.timer), - MySocket = StateData#state.socket, - Shaper = StateData#state.shaper, - Host = StateData#state.host, - MaxRate = find_maxrate(Shaper, IJid, TJid, Host), - spawn_link(?MODULE, relay, - [MySocket, PeerSocket, MaxRate]), - {next_state, stream_established, StateData}; -%% Socket closed -handle_info({tcp_closed, _Socket}, _StateName, - StateData) -> - {stop, normal, StateData}; -handle_info({tcp_error, _Socket, _Reason}, _StateName, - StateData) -> - {stop, normal, StateData}; -%% Got stop message. -handle_info(stop, _StateName, StateData) -> - {stop, normal, StateData}; -%% Either linked process or peer process died. -handle_info({'EXIT', _, _}, _StateName, StateData) -> - {stop, normal, StateData}; -handle_info({'DOWN', _, _, _, _}, _StateName, - StateData) -> - {stop, normal, StateData}; -%% Packets of no interest -handle_info(_Info, StateName, StateData) -> - {next_state, StateName, StateData}. - -%% Socket request. -handle_sync_event(get_socket, _From, - wait_for_activation, StateData) -> - Socket = StateData#state.socket, - {reply, Socket, wait_for_activation, StateData}; -handle_sync_event(_Event, _From, StateName, - StateData) -> - {reply, error, StateName, StateData}. - -%%%------------------------------------------------- -%%% Relay Process. -%%%------------------------------------------------- -relay(MySocket, PeerSocket, Shaper) -> - case gen_tcp:recv(MySocket, 0) of - {ok, Data} -> - gen_tcp:send(PeerSocket, Data), - {NewShaper, Pause} = shaper:update(Shaper, byte_size(Data)), - if Pause > 0 -> timer:sleep(Pause); - true -> pass - end, - relay(MySocket, PeerSocket, NewShaper); - _ -> stopped - end. - -%%%------------------------ -%%% Auxiliary functions -%%%------------------------ -select_auth_method(plain, AuthMethods) -> - case lists:member(?AUTH_PLAIN, AuthMethods) of - true -> ?AUTH_PLAIN; - false -> ?AUTH_NO_METHODS - end; -select_auth_method(anonymous, AuthMethods) -> - case lists:member(?AUTH_ANONYMOUS, AuthMethods) of - true -> ?AUTH_ANONYMOUS; - false -> ?AUTH_NO_METHODS - end. - -%% Obviously, we must use shaper with maximum rate. -find_maxrate(Shaper, JID1, JID2, Host) -> - MaxRate1 = shaper:new(acl:match_rule(Host, Shaper, - JID1)), - MaxRate2 = shaper:new(acl:match_rule(Host, Shaper, - JID2)), - if MaxRate1 == none; MaxRate2 == none -> none; - true -> lists:max([MaxRate1, MaxRate2]) - end. -- cgit v1.2.3