fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/logger_gsmtap/+/39553?usp=email )
Change subject: Create GSMTAP sink to avoid ICMP errors ......................................................................
Create GSMTAP sink to avoid ICMP errors
Change-Id: I1b103bb16d2e9f0bc6296a2feda138364ed640e2 --- M src/logger_gsmtap.erl 1 file changed, 43 insertions(+), 8 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/logger_gsmtap refs/changes/53/39553/1
diff --git a/src/logger_gsmtap.erl b/src/logger_gsmtap.erl index 570952d..d4ce411 100644 --- a/src/logger_gsmtap.erl +++ b/src/logger_gsmtap.erl @@ -21,6 +21,7 @@ -export([init/1, handle_call/3, handle_cast/2, + handle_info/2, terminate/2]).
-define(GSMTAP_PORT, 4729). @@ -56,11 +57,8 @@ %% ------------------------------------------------------------------
init([LAddr, RAddr, AppName]) -> - {ok, Sock} = gen_udp:open(0, [binary, - {ip, LAddr}, %% bind addr - {reuseaddr, true}]), - ok = gen_udp:connect(Sock, RAddr, ?GSMTAP_PORT), - {ok, #{sock => Sock, + {ok, #{sock_source => create_source(LAddr, RAddr), + sock_sink => create_sink(RAddr), app_name => AppName}}.
@@ -69,7 +67,7 @@
handle_cast({log, LogEvent}, - #{sock := Sock, + #{sock_source := Sock, app_name := AppName} = S) -> PDU = gsmtap_pdu(LogEvent#{app_name => AppName}), gen_udp:send(Sock, PDU), @@ -79,8 +77,13 @@ {noreply, S}.
-terminate(_Reason, #{sock := Sock}) -> - gen_udp:close(Sock), +handle_info(_Info, S) -> + {noreply, S}. + + +terminate(_Reason, S) -> + close(maps:get(sock_source, S)), + close(maps:get(sock_sink, S)), ok.
@@ -88,6 +91,38 @@ %% private API %% ------------------------------------------------------------------
+-spec create_source(LAddr, RAddr) -> gen_udp:socket() + when LAddr :: inet:ip_address(), + RAddr :: inet:ip_address(). +create_source(LAddr, RAddr) -> + {ok, Sock} = gen_udp:open(0, [binary, + {ip, LAddr}, %% bind addr + {reuseaddr, true}, + {active, false}]), + ok = gen_udp:connect(Sock, RAddr, ?GSMTAP_PORT), + Sock. + + +-spec create_sink(inet:ip_address()) -> gen_udp:socket() | nope. +create_sink(Addr) -> + %% it's not critical if gen_udp:open/2 fails + case gen_udp:open(?GSMTAP_PORT, [binary, + {ip, Addr}, %% bind addr + {reuseaddr, true}, + {active, false}]) of + {ok, Sock} -> Sock; + _ -> nope + end. + + +-spec close(nope | gen_udp:socket()) -> ok. +close(nope) -> + ok; + +close(Sock) -> + gen_udp:close(Sock). + + -spec gsmtap_pdu(map()) -> binary(). gsmtap_pdu(#{msg := Msg, level := Level,