Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/stun/stun_codec.erl')
-rw-r--r--src/stun/stun_codec.erl305
1 files changed, 0 insertions, 305 deletions
diff --git a/src/stun/stun_codec.erl b/src/stun/stun_codec.erl
deleted file mode 100644
index 4d489e070..000000000
--- a/src/stun/stun_codec.erl
+++ /dev/null
@@ -1,305 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File : stun_codec.erl
-%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : STUN codec
-%%% Created : 7 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% 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(stun_codec).
-
-%% API
--export([decode/1, encode/1, version/1, reason/1,
- pp/1]).
-
-%% Tests
--export([test_udp/2, test_tcp/2, test_tls/2,
- test_public/0]).
-
--include("stun.hrl").
-
-%%====================================================================
-%% API
-%%====================================================================
-decode(<<0:2, Type:14, Len:16, Magic:32, TrID:96,
- Body:Len/binary, Tail/binary>>) ->
- case catch decode(Type, Magic, TrID, Body) of
- {'EXIT', _} -> {error, unparsed};
- Res -> {ok, Res, Tail}
- end;
-decode(<<0:2, _/binary>>) -> more;
-decode(<<>>) -> empty;
-decode(_) -> {error, unparsed}.
-
-encode(#stun{class = Class, method = Method,
- magic = Magic, trid = TrID} =
- Msg) ->
- ClassCode = case Class of
- request -> 0;
- indication -> 1;
- response -> 2;
- error -> 3
- end,
- Type = (?STUN_TYPE(ClassCode, Method)),
- Attrs = enc_attrs(Msg),
- Len = byte_size(Attrs),
- <<0:2, Type:14, Len:16, Magic:32, TrID:96,
- Attrs/binary>>.
-
-pp(Term) -> io_lib_pretty:print(Term, fun pp/2).
-
-version(#stun{magic = ?STUN_MAGIC}) -> new;
-version(#stun{}) -> old.
-
-reason(300) -> <<"Try Alternate">>;
-reason(400) -> <<"Bad Request">>;
-reason(401) -> <<"Unauthorized">>;
-reason(420) -> <<"Unknown Attribute">>;
-reason(438) -> <<"Stale Nonce">>;
-reason(500) -> <<"Server Error">>;
-reason(_) -> <<"Undefined Error">>.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-decode(Type, Magic, TrID, Body) ->
- Method = (?STUN_METHOD(Type)),
- Class = case ?STUN_CLASS(Type) of
- 0 -> request;
- 1 -> indication;
- 2 -> response;
- 3 -> error
- end,
- dec_attrs(Body,
- #stun{class = Class, method = Method, magic = Magic,
- trid = TrID}).
-
-dec_attrs(<<Type:16, Len:16, Rest/binary>>, Msg) ->
- PaddLen = padd_len(Len),
- <<Val:Len/binary, _:PaddLen, Tail/binary>> = Rest,
- NewMsg = dec_attr(Type, Val, Msg),
- if Type == (?STUN_ATTR_MESSAGE_INTEGRITY) -> NewMsg;
- true -> dec_attrs(Tail, NewMsg)
- end;
-dec_attrs(<<>>, Msg) -> Msg.
-
-enc_attrs(Msg) ->
- iolist_to_binary([enc_attr(?STUN_ATTR_SOFTWARE,
- Msg#stun.'SOFTWARE'),
- enc_addr(?STUN_ATTR_MAPPED_ADDRESS,
- Msg#stun.'MAPPED-ADDRESS'),
- enc_xor_addr(?STUN_ATTR_XOR_MAPPED_ADDRESS,
- Msg#stun.magic, Msg#stun.trid,
- Msg#stun.'XOR-MAPPED-ADDRESS'),
- enc_addr(?STUN_ATTR_ALTERNATE_SERVER,
- Msg#stun.'ALTERNATE-SERVER'),
- enc_attr(?STUN_ATTR_USERNAME, Msg#stun.'USERNAME'),
- enc_attr(?STUN_ATTR_REALM, Msg#stun.'REALM'),
- enc_attr(?STUN_ATTR_NONCE, Msg#stun.'NONCE'),
- enc_error_code(Msg#stun.'ERROR-CODE'),
- enc_unknown_attrs(Msg#stun.'UNKNOWN-ATTRIBUTES')]).
-
-dec_attr(?STUN_ATTR_MAPPED_ADDRESS, Val, Msg) ->
- <<_, Family, Port:16, AddrBin/binary>> = Val,
- Addr = dec_addr(Family, AddrBin),
- Msg#stun{'MAPPED-ADDRESS' = {Addr, Port}};
-dec_attr(?STUN_ATTR_XOR_MAPPED_ADDRESS, Val, Msg) ->
- <<_, Family, XPort:16, XAddr/binary>> = Val,
- Magic = Msg#stun.magic,
- Port = XPort bxor (Magic bsr 16),
- Addr = dec_xor_addr(Family, Magic, Msg#stun.trid,
- XAddr),
- Msg#stun{'XOR-MAPPED-ADDRESS' = {Addr, Port}};
-dec_attr(?STUN_ATTR_SOFTWARE, Val, Msg) ->
- Msg#stun{'SOFTWARE' = Val};
-dec_attr(?STUN_ATTR_USERNAME, Val, Msg) ->
- Msg#stun{'USERNAME' = Val};
-dec_attr(?STUN_ATTR_REALM, Val, Msg) ->
- Msg#stun{'REALM' = Val};
-dec_attr(?STUN_ATTR_NONCE, Val, Msg) ->
- Msg#stun{'NONCE' = Val};
-dec_attr(?STUN_ATTR_MESSAGE_INTEGRITY, Val, Msg) ->
- Msg#stun{'MESSAGE-INTEGRITY' = Val};
-dec_attr(?STUN_ATTR_ALTERNATE_SERVER, Val, Msg) ->
- <<_, Family, Port:16, Address/binary>> = Val,
- IP = dec_addr(Family, Address),
- Msg#stun{'ALTERNATE-SERVER' = {IP, Port}};
-dec_attr(?STUN_ATTR_ERROR_CODE, Val, Msg) ->
- <<_:21, Class:3, Number:8, Reason/binary>> = Val,
- if Class >= 3, Class =< 6, Number >= 0, Number =< 99 ->
- Code = Class * 100 + Number,
- Msg#stun{'ERROR-CODE' = {Code, Reason}}
- end;
-dec_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES, Val, Msg) ->
- Attrs = dec_unknown_attrs(Val, []),
- Msg#stun{'UNKNOWN-ATTRIBUTES' = Attrs};
-dec_attr(Attr, _Val, #stun{unsupported = Attrs} = Msg)
- when Attr =< 32767 ->
- Msg#stun{unsupported = [Attr | Attrs]};
-dec_attr(_Attr, _Val, Msg) -> Msg.
-
-dec_addr(1, <<A1, A2, A3, A4>>) -> {A1, A2, A3, A4};
-dec_addr(2,
- <<A1:16, A2:16, A3:16, A4:16, A5:16, A6:16, A7:16,
- A8:16>>) ->
- {A1, A2, A3, A4, A5, A6, A7, A8}.
-
-dec_xor_addr(1, Magic, _TrID, <<XAddr:32>>) ->
- Addr = XAddr bxor Magic, dec_addr(1, <<Addr:32>>);
-dec_xor_addr(2, Magic, TrID, <<XAddr:128>>) ->
- Addr = XAddr bxor (Magic bsl 96 bor TrID),
- dec_addr(2, <<Addr:128>>).
-
-dec_unknown_attrs(<<Attr:16, Tail/binary>>, Acc) ->
- dec_unknown_attrs(Tail, [Attr | Acc]);
-dec_unknown_attrs(<<>>, Acc) -> lists:reverse(Acc).
-
-enc_attr(_Attr, undefined) -> <<>>;
-enc_attr(Attr, Val) ->
- Len = byte_size(Val),
- PaddLen = padd_len(Len),
- <<Attr:16, Len:16, Val/binary, 0:PaddLen>>.
-
-enc_addr(_Type, undefined) -> <<>>;
-enc_addr(Type, {{A1, A2, A3, A4}, Port}) ->
- enc_attr(Type, <<0, 1, Port:16, A1, A2, A3, A4>>);
-enc_addr(Type,
- {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) ->
- enc_attr(Type,
- <<0, 2, Port:16, A1:16, A2:16, A3:16, A4:16, A5:16,
- A6:16, A7:16, A8:16>>).
-
-enc_xor_addr(_Type, _Magic, _TrID, undefined) -> <<>>;
-enc_xor_addr(Type, Magic, _TrID,
- {{A1, A2, A3, A4}, Port}) ->
- XPort = Port bxor (Magic bsr 16),
- <<Addr:32>> = <<A1, A2, A3, A4>>,
- XAddr = Addr bxor Magic,
- enc_attr(Type, <<0, 1, XPort:16, XAddr:32>>);
-enc_xor_addr(Type, Magic, TrID,
- {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) ->
- XPort = Port bxor (Magic bsr 16),
- <<Addr:128>> = <<A1:16, A2:16, A3:16, A4:16, A5:16,
- A6:16, A7:16, A8:16>>,
- XAddr = Addr bxor (Magic bsl 96 bor TrID),
- enc_attr(Type, <<0, 2, XPort:16, XAddr:128>>).
-
-enc_error_code(undefined) -> <<>>;
-enc_error_code({Code, Reason}) ->
- Class = Code div 100,
- Number = Code rem 100,
- enc_attr(?STUN_ATTR_ERROR_CODE,
- <<0:21, Class:3, Number:8, Reason/binary>>).
-
-enc_unknown_attrs([]) -> <<>>;
-enc_unknown_attrs(Attrs) ->
- enc_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES,
-%%====================================================================
-%% Auxiliary functions
-%%====================================================================
- iolist_to_binary([<<Attr:16>> || Attr <- Attrs])).
-
-pp(Tag, N) -> try pp1(Tag, N) catch _:_ -> no end.
-
-pp1(stun, N) ->
- N = record_info(size, stun) - 1,
- record_info(fields, stun);
-pp1(_, _) -> no.
-
-%% Workaround for stupid clients.
--ifdef(NO_PADDING).
-
-padd_len(_Len) -> 0.
-
--else.
-
-padd_len(Len) ->
- case Len rem 4 of
- 0 -> 0;
- N -> 8 * (4 - N)
- end.
-
--endif.
-
-%%====================================================================
-%% Test functions
-%%====================================================================
-bind_msg() ->
- Msg = #stun{method = ?STUN_METHOD_BINDING,
- class = request, trid = random:uniform(1 bsl 96),
- 'SOFTWARE' = <<"test">>},
- encode(Msg).
-
-test_udp(Addr, Port) -> test(Addr, Port, gen_udp).
-
-test_tcp(Addr, Port) -> test(Addr, Port, gen_tcp).
-
-test_tls(Addr, Port) -> test(Addr, Port, ssl).
-
-test(Addr, Port, Mod) ->
- Res = case Mod of
- gen_udp -> Mod:open(0, [binary, {active, false}]);
- _ ->
- Mod:connect(Addr, Port, [binary, {active, false}], 1000)
- end,
- case Res of
- {ok, Sock} ->
- if Mod == gen_udp ->
- Mod:send(Sock, Addr, Port, bind_msg());
- true -> Mod:send(Sock, bind_msg())
- end,
- case Mod:recv(Sock, 0, 1000) of
- {ok, {_, _, Data}} -> try_dec(Data);
- {ok, Data} -> try_dec(Data);
- Err -> io:format("err: ~p~n", [Err])
- end,
- Mod:close(Sock);
- Err -> io:format("err: ~p~n", [Err])
- end.
-
-try_dec(Data) ->
- case decode(Data) of
- {ok, Msg, _} -> io:format("got:~n~s~n", [pp(Msg)]);
- Err -> io:format("err: ~p~n", [Err])
- end.
-
-public_servers() ->
- [{"stun.ekiga.net", 3478, 3478, 5349},
- {"stun.ideasip.com", 3478, 3478, 5349},
- {"stun.softjoys.com", 3478, 3478, 5349},
- {"stun.voipbuster.com", 3478, 3478, 5349},
- {"stun.voxgratia.org", 3478, 3478, 5349},
- {"stunserver.org", 3478, 3478, 5349},
- {"stun.sipgate.net", 10000, 10000, 5349},
- {"numb.viagenie.ca", 3478, 3478, 5349},
- {"stun.ipshka.com", 3478, 3478, 5349},
- {"localhost", 3478, 5349, 5349}].
-
-test_public() ->
- ssl:start(),
- lists:foreach(fun ({Addr, UDPPort, TCPPort, TLSPort}) ->
- io:format("trying ~s:~p on UDP... ", [Addr, UDPPort]),
- test_udp(Addr, UDPPort),
- io:format("trying ~s:~p on TCP... ", [Addr, TCPPort]),
- test_tcp(Addr, TCPPort),
- io:format("trying ~s:~p on TLS... ", [Addr, TLSPort]),
- test_tls(Addr, TLSPort)
- end,
- public_servers()).