From 678d8edb128c40d6ae5d4492e6b85c94867be80a Mon Sep 17 00:00:00 2001 From: Louis-Philippe Gauthier Date: Tue, 14 Jun 2016 08:42:25 -0400 Subject: [PATCH] Support OTP-19-rc2 --- rebar.config | 3 ++- src/statsderl_server.erl | 10 ++++----- src/statsderl_udp.erl | 44 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/statsderl_udp.erl diff --git a/rebar.config b/rebar.config index 9a63404..49240fe 100644 --- a/rebar.config +++ b/rebar.config @@ -13,7 +13,8 @@ ]}. {erl_opts, [ - debug_info + debug_info, + {platform_define, "19", 'UDP_HEADER'} ]}. {profiles, [ diff --git a/src/statsderl_server.erl b/src/statsderl_server.erl index 3fa4746..8154464 100644 --- a/src/statsderl_server.erl +++ b/src/statsderl_server.erl @@ -7,7 +7,7 @@ ]). -record(state, { - header :: binary(), + header :: iodata(), socket :: inet:socket() }). @@ -70,11 +70,9 @@ loop(State) -> udp_header(Hostname, Port, BaseKey) -> case statsderl_utils:getaddrs(Hostname) of {ok, {A, B, C, D}} -> - {ok, iolist_to_binary([ - [((Port) bsr 8) band 16#ff, (Port) band 16#ff], - [A band 16#ff, B band 16#ff, C band 16#ff, D band 16#ff], - statsderl_utils:base_key(BaseKey) - ])}; + Header = statsderl_udp:header({A, B, C, D}, Port), + BaseKey2 = statsderl_utils:base_key(BaseKey), + {ok, [Header, BaseKey2]}; {error, Reason} -> {error, Reason} end. diff --git a/src/statsderl_udp.erl b/src/statsderl_udp.erl new file mode 100644 index 0000000..9c4f6bf --- /dev/null +++ b/src/statsderl_udp.erl @@ -0,0 +1,44 @@ +-module(statsderl_udp). +-include("statsderl.hrl"). + +-compile(inline). +-compile({inline_size, 512}). + +-export([ + header/2, + send/3 +]). + +-define(INET_AF_INET, 1). +-define(INT16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]). + +%% public +-spec header(inet:ip_address(), inet:port_number()) -> iodata(). + +-ifdef(UDP_HEADER). + +header(IP, Port) -> + [?INET_AF_INET, ?INT16(Port) | ip4_to_bytes(IP)]. + +-else. + +header(IP, Port) -> + [?INT16(Port) | ip4_to_bytes(IP)]. + +-endif. + +-spec send(inet:socket(), iodata(), iodata()) -> + ok | {error, term()}. + +send(Socket, Header, Data) -> + try + true = erlang:port_command(Socket, [Header, Data]), + ok + catch + Error:Reason -> + {error, {Error, Reason}} + end. + +%% private +ip4_to_bytes({A, B, C, D}) -> + [A band 16#ff, B band 16#ff, C band 16#ff, D band 16#ff].