diff --git a/src/egeoip.erl b/src/egeoip.erl index 2e69d07..5fbb802 100644 --- a/src/egeoip.erl +++ b/src/egeoip.erl @@ -326,10 +326,10 @@ init(FileName) -> %% @spec handle_call(Msg, From, State) -> term() %% @doc gen_server callback. handle_call(What,From,State) -> - try + try do_handle_call(What,From,State) - catch - _:R -> + catch + _:R -> log_error([{handle_call,What},{error,R}]), {reply,{error,R},State} end. @@ -386,13 +386,13 @@ new(city) -> new(default_db(["GeoIPCity.dat", "GeoLiteCity.dat"])); new(Path) -> case filelib:is_file(Path) of - true -> - Data = load_file(Path), - Max = ?STRUCTURE_INFO_MAX_SIZE, - R = {ok, State} = read_structures(Path, Data, size(Data) - 3, Max), + true -> + Data = load_file(Path), + Max = ?STRUCTURE_INFO_MAX_SIZE, + R = {ok, State} = read_structures(Path, Data, size(Data) - 3, Max), ok = check_state(State), R; - false -> + false -> {error, {geoip_db_not_found,Path}} end. @@ -402,10 +402,10 @@ lookup(D, Addr) when is_list(Addr); is_tuple(Addr); is_binary(Addr) -> case ip2long(Addr) of - {ok, Ip} -> - lookup(D, Ip); - Error -> - Error + {ok, Ip} -> + lookup(D, Ip); + Error -> + Error end; lookup(D, Addr) when is_integer(Addr) -> get_record(D, Addr). @@ -423,33 +423,33 @@ default_db([Path | Rest]) -> address_fast([N2, N1, N0, $. | Rest], Num, Shift) when Shift >= 8 -> case list_to_integer([N2, N1, N0]) of - N when N =< 255 -> - address_fast(Rest, Num bor (N bsl Shift), Shift - 8) + N when N =< 255 -> + address_fast(Rest, Num bor (N bsl Shift), Shift - 8) end; address_fast([N1, N0, $. | Rest], Num, Shift) when Shift >= 8 -> case list_to_integer([N1, N0]) of - N when N =< 255 -> - address_fast(Rest, Num bor (N bsl Shift), Shift - 8) + N when N =< 255 -> + address_fast(Rest, Num bor (N bsl Shift), Shift - 8) end; address_fast([N0, $. | Rest], Num, Shift) when Shift >= 8 -> case N0 - $0 of - N when N =< 255 -> - address_fast(Rest, Num bor (N bsl Shift), Shift - 8) + N when N =< 255 -> + address_fast(Rest, Num bor (N bsl Shift), Shift - 8) end; address_fast(L=[_N2, _N1, _N0], Num, 0) -> case list_to_integer(L) of - N when N =< 255 -> - Num bor N + N when N =< 255 -> + Num bor N end; address_fast(L=[_N1, _N0], Num, 0) -> case list_to_integer(L) of - N when N =< 255 -> - Num bor N + N when N =< 255 -> + Num bor N end; address_fast([N0], Num, 0) -> case N0 - $0 of - N when N =< 255 -> - Num bor N + N when N =< 255 -> + Num bor N end. %% @spec ip2long(Address) -> {ok, integer()} @@ -459,21 +459,21 @@ ip2long(Address) when is_integer(Address) -> {ok, Address}; ip2long(Address) when is_list(Address) -> case catch address_fast(Address, 0, 24) of - N when is_integer(N) -> - {ok, N}; - _ -> - case inet_parse:address(Address) of - {ok, Tuple} -> - ip2long(Tuple); - Error -> - Error - end + N when is_integer(N) -> + {ok, N}; + _ -> + case inet_parse:address(Address) of + {ok, Tuple} -> + ip2long(Tuple); + Error -> + Error + end end; ip2long({B3, B2, B1, B0}) -> {ok, (B3 bsl 24) bor (B2 bsl 16) bor (B1 bsl 8) bor B0}; ip2long({W7, W6, W5, W4, W3, W2, W1, W0}) -> {ok, (W7 bsl 112) bor (W6 bsl 96) bor (W5 bsl 80) bor (W4 bsl 64) bor - (W3 bsl 48) bor (W2 bsl 32) bor (W1 bsl 16) bor W0}; + (W3 bsl 48) bor (W2 bsl 32) bor (W1 bsl 16) bor W0}; ip2long(<>) -> {ok, Addr}; ip2long(<>) -> @@ -483,10 +483,10 @@ ip2long(_) -> get_record(D, Ip) -> case seek_country(D, Ip) of - {ok, SeekCountry} -> - get_record(D, Ip, SeekCountry); - Error -> - Error + {ok, SeekCountry} -> + get_record(D, Ip, SeekCountry); + Error -> + Error end. @@ -496,44 +496,44 @@ read_structures(_Path, _Data, _, 0) -> read_structures(Path, Data, Seek, N) -> <<_:Seek/binary, Delim:3/binary, _/binary>> = Data, case Delim of - <<255, 255, 255>> -> - <<_:Seek/binary, _:3/binary, DbType, _/binary>> = Data, - Type = case DbType >= 106 of - true -> - DbType - 105; - false -> - DbType - end, - Segments = case Type of - ?GEOIP_REGION_EDITION_REV0 -> - ?GEOIP_STATE_BEGIN_REV0; - ?GEOIP_REGION_EDITION_REV1 -> - ?GEOIP_STATE_BEGIN_REV1; - ?GEOIP_COUNTRY_EDITION -> - ?GEOIP_COUNTRY_BEGIN; - ?GEOIP_PROXY_EDITION -> - ?GEOIP_COUNTRY_BEGIN; - ?GEOIP_NETSPEED_EDITION -> - ?GEOIP_COUNTRY_BEGIN; - _ -> - read_segments(Type, Data, Seek + 4) - end, - Length = case Type of - ?GEOIP_ORG_EDITION -> - ?ORG_RECORD_LENGTH; - ?GEOIP_ISP_EDITION -> - ?ORG_RECORD_LENGTH; - _ -> - ?STANDARD_RECORD_LENGTH - end, - Rec = #geoipdb{type = Type, - segments = Segments, - record_length = Length, - data = Data, - filename = Path}, - {ok, Rec}; - _ -> - read_structures(Path, Data, Seek - 1, N - 1) + <<255, 255, 255>> -> + <<_:Seek/binary, _:3/binary, DbType, _/binary>> = Data, + Type = case DbType >= 106 of + true -> + DbType - 105; + false -> + DbType + end, + Segments = case Type of + ?GEOIP_REGION_EDITION_REV0 -> + ?GEOIP_STATE_BEGIN_REV0; + ?GEOIP_REGION_EDITION_REV1 -> + ?GEOIP_STATE_BEGIN_REV1; + ?GEOIP_COUNTRY_EDITION -> + ?GEOIP_COUNTRY_BEGIN; + ?GEOIP_PROXY_EDITION -> + ?GEOIP_COUNTRY_BEGIN; + ?GEOIP_NETSPEED_EDITION -> + ?GEOIP_COUNTRY_BEGIN; + _ -> + read_segments(Type, Data, Seek + 4) + end, + Length = case Type of + ?GEOIP_ORG_EDITION -> + ?ORG_RECORD_LENGTH; + ?GEOIP_ISP_EDITION -> + ?ORG_RECORD_LENGTH; + _ -> + ?STANDARD_RECORD_LENGTH + end, + Rec = #geoipdb{type = Type, + segments = Segments, + record_length = Length, + data = Data, + filename = Path}, + {ok, Rec}; + _ -> + read_structures(Path, Data, Seek - 1, N - 1) end. @@ -555,15 +555,15 @@ get_record(D, _Ip, SeekCountry) -> Type = D#geoipdb.type, {DmaCode, AreaCode} = get_record_ex(Type, Country, Data, Seek3 + 6), Record = #geoip{country_code = Country, - country_code3 = Country3, - country_name = CountryName, - region = Region, - city = City, - postal_code = Postal, - latitude = Lat, - longitude = Lon, - dma_code = DmaCode, - area_code = AreaCode}, + country_code3 = Country3, + country_name = CountryName, + region = Region, + city = City, + postal_code = Postal, + latitude = Lat, + longitude = Lon, + dma_code = DmaCode, + area_code = AreaCode}, {ok, Record}. get_record_ex(?GEOIP_CITY_EDITION_REV1, "US", Data, Seek) -> @@ -585,26 +585,26 @@ seek_country(D, Ip, Offset, Depth) -> Seek = 2 * RecordLength * Offset, <<_:Seek/binary, X0:RB/little, X1:RB/little, _/binary>> = D#geoipdb.data, X = case (Ip band (1 bsl Depth)) of - 0 -> X0; - _ -> X1 - end, + 0 -> X0; + _ -> X1 + end, case (X >= D#geoipdb.segments) of - true -> - {ok, X}; - false -> - seek_country(D, Ip, X, Depth - 1) + true -> + {ok, X}; + false -> + seek_country(D, Ip, X, Depth - 1) end. until_null(Binary, Start, Index) -> Skip = Start + Index, <<_:Skip/binary, Byte, _/binary>> = Binary, case Byte of - 0 -> - Length = Skip - Start, - <<_:Start/binary, Result:Length/binary, _/binary>> = Binary, - {Result, 1 + Skip}; - _ -> - until_null(Binary, Start, 1 + Index) + 0 -> + Length = Skip - Start, + <<_:Start/binary, Result:Length/binary, _/binary>> = Binary, + {Result, 1 + Skip}; + _ -> + until_null(Binary, Start, 1 + Index) end. check_state(D) -> @@ -615,30 +615,30 @@ check_state(D) -> country_code(D, Number) -> try - element(Number, D#geoipdb.country_codes) + element(Number, D#geoipdb.country_codes) catch - error:badarg -> "" + error:badarg -> "" end. country_code3(D, Number) -> try - element(Number, D#geoipdb.country_codes3) + element(Number, D#geoipdb.country_codes3) catch - error:badarg -> "" + error:badarg -> "" end. country_name(D, Number) -> try - element(Number, D#geoipdb.country_names) + element(Number, D#geoipdb.country_names) catch - error:badarg -> "" + error:badarg -> "" end. read_segments(Type, Data, Seek) when Type == ?GEOIP_CITY_EDITION_REV0; - Type == ?GEOIP_CITY_EDITION_REV1; - Type == ?GEOIP_ORG_EDITION; - Type == ?GEOIP_ISP_EDITION; - Type == ?GEOIP_ASNUM_EDITION -> + Type == ?GEOIP_CITY_EDITION_REV1; + Type == ?GEOIP_ORG_EDITION; + Type == ?GEOIP_ISP_EDITION; + Type == ?GEOIP_ASNUM_EDITION -> Bits = ?SEGMENT_RECORD_LENGTH * 8, <<_:Seek/binary, Segments:Bits/little, _/binary>> = Data, Segments. @@ -653,13 +653,13 @@ priv_path(Components) -> load_file(Path) -> case file:read_file(Path) of - {ok, Raw} -> - case filename:extension(Path) of - ".gz" -> - zlib:gunzip(Raw); - _ -> - Raw - end + {ok, Raw} -> + case filename:extension(Path) of + ".gz" -> + zlib:gunzip(Raw); + _ -> + Raw + end end. benchcall(Fun, 1) -> @@ -673,15 +673,15 @@ pytime({MegaSecs, Secs, MicroSecs}) -> bench(Count) -> SampleIPs = ["63.224.214.117", - "144.139.80.91", - "88.233.53.82", - "85.250.32.5", - "220.189.211.182", - "211.112.118.99", - "84.94.205.244", - "61.16.226.206", - "64.180.1.78", - "138.217.4.11"], + "144.139.80.91", + "88.233.53.82", + "85.250.32.5", + "220.189.211.182", + "211.112.118.99", + "84.94.205.244", + "61.16.226.206", + "64.180.1.78", + "138.217.4.11"], StartParse = now(), benchcall(fun () -> [lookup(X) || X <- SampleIPs] end, Count), EndParse = now(), diff --git a/src/egeoip_acl.erl b/src/egeoip_acl.erl index 66ee515..dbf58fa 100644 --- a/src/egeoip_acl.erl +++ b/src/egeoip_acl.erl @@ -1,8 +1,8 @@ -module(egeoip_acl). -export([ - parse_file/1, - lookup/2 -]). + parse_file/1, + lookup/2 + ]). %% @type ip24() = list() | binary() | {int(), int(), int()} %% @type ip32() = list() | binary() | {int(), int(), int(), int()} @@ -44,19 +44,19 @@ parse_file(Filename) -> {IPsBlob, IPsIndex, Zones}. %% @spec lookup(ip(), acldb()) -> binary() | notfound | invalid_ip -%% @doc Searches for 24-bit or 32-bit IP in the database generated from ACL +%% @doc Searches for 24-bit or 32-bit IP in the database generated from ACL %% file. Returns a binary name of the zone or 'notfound' if there's no %% zone associated with the IP. lookup(invalid_ip, _) -> invalid_ip; lookup(<>, {IPsBlob, IPsIndex, Zones}) -> IndexOffset = Prefix * 4, << _:(IndexOffset)/binary, - BucketOffset:16/integer, - BucketSize:16/integer, - _/binary >> = IPsIndex, + BucketOffset:16/integer, + BucketSize:16/integer, + _/binary >> = IPsIndex, << _:(BucketOffset)/binary, - Ranges:(BucketSize)/binary, - _/binary >> = IPsBlob, + Ranges:(BucketSize)/binary, + _/binary >> = IPsBlob, case lookup_ip(C, Ranges) of V when is_integer(V) -> element(V, Zones); @@ -73,9 +73,9 @@ parse_ip(IP) when is_binary(IP) -> parse_ip(binary_to_list(IP)); parse_ip(IP) when is_list(IP) -> case lists:map( - fun list_to_integer/1, - string:tokens(IP, ".") - ) of + fun list_to_integer/1, + string:tokens(IP, ".") + ) of [A, B, C] -> <>; [A, B, C, _] -> <>; _ -> invalid_ip @@ -88,14 +88,14 @@ lookup_ip(C, Bin) -> Left = Size div 2, Right = Size - Left - 1, << Prefix:Left/binary-unit:32, - Start:8, End:8, ZNum:16/integer, - Suffix:Right/binary-unit:32 >> = Bin, + Start:8, End:8, ZNum:16/integer, + Suffix:Right/binary-unit:32 >> = Bin, case C of C when C < Start -> lookup_ip(C, Prefix); C when C > End -> lookup_ip(C, Suffix); - C when C >= Start, C =< End -> + C when C >= Start, C =< End -> ZNum; C -> notfound end. @@ -129,11 +129,11 @@ parse_line([_ | T], Zones) -> %% sorting. parse_ips(IPsBin) -> reduce_ips( - lists:sort( - split_ips(IPsBin, []) - ), - [] - ). + lists:sort( + split_ips(IPsBin, []) + ), + [] + ). split_ips(<<>>, Acc) -> Acc; split_ips(<<"\n", Rest/binary>>, Acc) -> @@ -155,14 +155,14 @@ split_ips(<>, Acc) -> parse_ip24(IP) -> [A, B, C] = lists:map( - fun list_to_integer/1, - string:tokens(binary_to_list(IP), ".") - ), + fun list_to_integer/1, + string:tokens(binary_to_list(IP), ".") + ), <>. reduce_ips([], Groups) -> Groups; reduce_ips([<> | IPs], [<> | Groups]) - when End =:= C - 1 -> + when End =:= C - 1 -> reduce_ips(IPs, [<> | Groups]); reduce_ips([<> | IPs], Groups) -> reduce_ips(IPs, [<> | Groups]). @@ -170,34 +170,34 @@ reduce_ips([<> | IPs], Groups) -> zones_index(IPsByZones) -> ZonesList = [Zone || {Zone, _IPs} <- IPsByZones], {ZonesTree, _} = lists:foldl( - fun (Zone, {Acc, Num}) -> - {gb_trees:insert(Zone, Num, Acc), Num + 1} - end, - {gb_trees:empty(), 1}, ZonesList), + fun (Zone, {Acc, Num}) -> + {gb_trees:insert(Zone, Num, Acc), Num + 1} + end, + {gb_trees:empty(), 1}, ZonesList), { - list_to_tuple(ZonesList), - ZonesTree + list_to_tuple(ZonesList), + ZonesTree }. extract_ips(IPsByZone, ZonesTree) -> lists:sort(lists:flatten([ - begin - {value, Num} = gb_trees:lookup(Zone, ZonesTree), - [{IP, Num} || IP <- IPs] - end - || {Zone, IPs} <- IPsByZone - ])). + begin + {value, Num} = gb_trees:lookup(Zone, ZonesTree), + [{IP, Num} || IP <- IPs] + end + || {Zone, IPs} <- IPsByZone + ])). ips_index(IPZoneKV) -> IPGroups = group_ips(IPZoneKV, []), ZeroIPsIndex = list_to_binary( - lists:duplicate(256 * 256, <<0:32/integer>>) - ), + lists:duplicate(256 * 256, <<0:32/integer>>) + ), merge_ip_groups(IPGroups, <<>>, ZeroIPsIndex). group_ips([], Groups) -> Groups; group_ips([{<>, Zone} | IPs], - [<> | Groups]) -> + [<> | Groups]) -> group_ips(IPs, [<> | Groups]); group_ips([{<>, Zone} | IPs], Groups) -> group_ips(IPs, [<> | Groups]). @@ -207,11 +207,11 @@ merge_ip_groups([<> | Groups], IPsBlob, IPsIndex) L = Addr * 4, <> = IPsIndex, merge_ip_groups(Groups, <>, - << Prefix/binary, - (byte_size(IPsBlob)):16/integer, - (byte_size(Ranges)):16/integer, - Suffix/binary >> - ). + << Prefix/binary, + (byte_size(IPsBlob)):16/integer, + (byte_size(Ranges)):16/integer, + Suffix/binary >> + ). %% %% Tests @@ -225,52 +225,41 @@ ip_parse_test() -> test_ips() -> [ - {<<192,168,0>>, <<"192.168.0">>}, - {<<200,23,11>>, <<"200.23.11">>}, - {<<127,127,127>>, <<"127.127.127">>} + {<<192,168,0>>, <<"192.168.0">>}, + {<<200,23,11>>, <<"200.23.11">>}, + {<<127,127,127>>, <<"127.127.127">>} ]. ips_parse_test() -> [ - <<60, 169, 4, 4>>, - <<60, 166, 7, 7>>, - <<60, 166, 3, 3>>, - <<60, 166, 0, 0>> + <<60, 169, 4, 4>>, + <<60, 166, 7, 7>>, + <<60, 166, 3, 3>>, + <<60, 166, 0, 0>> ] = parse_ips( - <<"60.166.0.0/24;60.166.7.0/24;\n60.166.3.0/24;60.169.4.0/24;">> - ), + <<"60.166.0.0/24;60.166.7.0/24;\n60.166.3.0/24;60.169.4.0/24;">> + ), ok. line_parse_test() -> - [ - - { - <<"CNC_AnHui">>, - [ - <<58, 243, 45, 45>>, - <<58, 242, 46, 48>> - ] - }, - { - <<"CT_AnHui">>, - [ - <<60, 166, 10, 13>>, - <<60, 166, 0, 3>> - ] - } - ] = parse_line(test_lines(), []), + [{<<"CNC_AnHui">>, + [<<58, 243, 45, 45>>, + <<58, 242, 46, 48>>]}, + {<<"CT_AnHui">>, + [<<60, 166, 10, 13>>, + <<60, 166, 0, 3>>]}] = parse_line(test_lines(), []), ok. test_lines() -> [ - <<"acl \"CT_AnHui\" {\n">>, - <<"60.166.0.0/24;60.166.1.0/24;60.166.2.0/24;60.166.3.0/24;\n">>, - <<"60.166.10.0/24;60.166.11.0/24;60.166.12.0/24;60.166.13.0/24;\n">>, - <<"};\n">>, - <<"acl \"CNC_AnHui\" {\n">>, - <<"58.243.45.0/24;58.242.46.0/24;58.242.47.0/24;58.242.48.0/24;\n">>, - <<"};\n">> + <<"acl \"CT_AnHui\" {\n">>, + <<"60.166.0.0/24;60.166.1.0/24;60.166.2.0/24;60.166.3.0/24;\n">>, + <<"60.166.10.0/24;60.166.11.0/24;60.166.12.0/24;60.166.13.0/24;\n">>, + <<"};\n">>, + <<"acl \"CNC_AnHui\" {\n">>, + <<"58.243.45.0/24;58.242.46.0/24;58.242.47.0/24;58.242.48.0/24;\n">>, + <<"};\n">> ]. -endif. diff --git a/src/egeoip_sup.erl b/src/egeoip_sup.erl index 405f2be..cde9955 100644 --- a/src/egeoip_sup.erl +++ b/src/egeoip_sup.erl @@ -37,5 +37,5 @@ worker([], _File) -> []; worker([Name | T], File) -> [{Name, - {egeoip, start_link, [Name, File]}, - permanent, 5000, worker, [egeoip]} | worker(T, File)]. + {egeoip, start_link, [Name, File]}, + permanent, 5000, worker, [egeoip]} | worker(T, File)]. diff --git a/src/egeoip_tz.erl b/src/egeoip_tz.erl index 490b87f..199da2c 100644 --- a/src/egeoip_tz.erl +++ b/src/egeoip_tz.erl @@ -4,7 +4,7 @@ -module(egeoip_tz). -export([utc_offset/1]). -record(geoip, {country_code, country_code3, country_name, region, - city, postal_code, latitude, longitude, area_code, dma_code}). + city, postal_code, latitude, longitude, area_code, dma_code}). utc_offset(#geoip{country_code = "US", region = <<"AL">>}) -> -21600; utc_offset(#geoip{country_code = "US", region = <<"AK">>}) -> -32400; utc_offset(#geoip{country_code = "US", region = <<"AZ">>}) -> -25200;