Skip to content
Permalink
Browse files

ioc2rpz is a place where threat intelligence meets DNS

  • Loading branch information...
Homas committed Jul 21, 2019
1 parent 0ec2e46 commit 999fe10881960ba996d2d0e5d7fe288a23dacda8
Showing with 78 additions and 51 deletions.
  1. +2 −1 ChangeLog.md
  2. +1 −1 Dockerfile
  3. +6 −7 TODO.md
  4. +1 −1 include/ioc2rpz.hrl
  5. +11 −0 src/ioc2rpz.erl
  6. +27 −33 src/ioc2rpz_db.erl
  7. +25 −3 src/ioc2rpz_fun.erl
  8. +5 −5 src/ioc2rpz_sup.erl
@@ -1,9 +1,10 @@
# ioc2rpz change log
[CB] - Changed Behaviour
## 2019-07-19 v0.9.5.0
## 2019-07-20 v0.9.5.0
- Bug fixes related to IXFR zone update and transfer
- [CB] Source IXFR update "from" time will be keept the same until we get "non zero" update.
- Retry for unavailable sources (see ioc2rpz.hrl)
- IXFR table management optimization

## 2019-06-13 v0.9.4.0
- Fixed bugs:
@@ -32,7 +32,7 @@ ADD include/* /opt/ioc2rpz/include/
ADD config/* /opt/ioc2rpz/config/
ADD rebar.config /opt/ioc2rpz/

RUN rebar3 release -d false
RUN rebar3 eunit && rebar3 release -d false

VOLUME ["/opt/ioc2rpz/cfg", "/opt/ioc2rpz/db"]

13 TODO.md
@@ -3,14 +3,12 @@
- [x] Add "reload_cert" API call (restart/reload cowboy) -- not needed. Erlang automatically reloads certificates. By default they are cached for 2 minutes.
- [x] Add links to ioc2rpz.net
- [x] Add links to the wiki's How-To install
- [ ] Start EUnit Tests
- [x] Start EUnit Tests
- [ ] Release 1.0
- [ ] Create development branch
- [ ] Create a development branch
- [ ] Update dockerhub images with 1.0 release
## Sources
- [ ] Add a script for RPZ via "shell:"
- [x] Retry if source was not available and handle the behaviour
- [ ] Simultanious source downloads
## Configuration
- [x] Validate: Configuration file name pass as a variable to the container
## UI
@@ -19,26 +17,27 @@

## Core / DNS
- [ ] RPZ storage type: ets, mnesia
- [ ] Mnesia for storage (and auto creation)
- [ ] Force AXRF for a RPZ if a source doesn't have an IXFR url
- [ ] Redo AXFR logs
- [ ] Access to the hotcache and the cfg_table via FUNs
- [ ] (1) Terminate updating zones during config reload
- [ ] (1) Clean up the code & add comments
- [ ] (*) saveZones - doesn't correctly save zones if there a lot of updates. Save strategy based on update size and time and currently running updates.
- [ ] Logs level startup config
- [ ] Check delete in ioc2rpz: rpz_hotcache_table/pkthotcache

- [ ] Mnesia for storage (and auto creation)
- [ ] Distributed configuration
- [ ] Wait while a remote server confirms receiving a notification
- [ ] (2) EDNS0 Support: DNS Cookie, edns-tcp-keepalive, NSID
- [ ] (3) Memory optimization for huge zones (erl -pa ebin +MEas bf ?????)
- [ ] DoH https://tools.ietf.org/html/rfc8484
- [ ] DoD https://tools.ietf.org/html/draft-ietf-dprive-dnsodtls-06

- [ ] EUnit Tests
- [ ] EUnit Tests for main funs.

## Sources
- [ ] Add a script for RPZ via "shell:"
- [ ] Simultanious source downloads
- [ ] Add source PostreSQL, MySQL via "shell:"
- [ ] Dedup IoC from different sources with different expiration dates
- [ ] RPZ action per source
@@ -28,7 +28,7 @@
-define(Src_Retry,3). %# of retries if a source is not available
-define(Src_Retry_TimeOut,3). %timeout between retries in seconds

%-define(logTS, true). % Log timestamps (comment or uncomment)
-define(logTS, true). % Log timestamps
-define(debug, true). % Log debug messages
-define(ioc2rpzSampleRPZ,"sample-zone.ioc2rpz"). %Default DB location

@@ -15,6 +15,7 @@
%IOC2RPZ TCP Worker

-module(ioc2rpz).
-include_lib("eunit/include/eunit.hrl").
-behaviour(gen_server).

-include_lib("ioc2rpz.hrl").
@@ -1188,3 +1189,13 @@ init_T_ZIP_L(Zone) ->
ets:insert(T_ZIP_L, {Labels, ?ZNameZipN}),
T_ZIP_L.

%%%%
%%%% EUnit tests
%%%%

reverse_IP_test() ->[
?assert(reverse_IP(<<"10.20.30.40">>) =:= <<"32.40.30.20.10">>),
?assert(reverse_IP(<<"10.20.30.40/24">>) =:= <<"24.40.30.20.10">>),
?assert(reverse_IP(<<"fc00:01::01">>) =:= <<"128.01.zz.01.fc00">>),
?assert(reverse_IP(<<"fc00::01/64">>) =:= <<"64.01.zz.fc00">>)
].
@@ -27,7 +27,7 @@ init_db(ets,DBDir,PID) ->
true -> ets:give_away(rpz_axfr_table, PID, [])
end,
if STI /= ok ->
ets:new(rpz_ixfr_table, [{heir,PID,[]}, {read_concurrency, true}, {write_concurrency, true}, set, public, named_table]);
ets:new(rpz_ixfr_table, [{heir,PID,[]}, {read_concurrency, true}, {write_concurrency, true}, duplicate_bag, public, named_table]); %set
true -> ets:give_away(rpz_ixfr_table, PID, [])
end,
ets:new(cfg_table, [{heir,PID,[]}, {read_concurrency, true}, {write_concurrency, true}, ordered_set, public, named_table]),
@@ -86,24 +86,24 @@ delete_db_pkt(mnesia,Zone) ->
read_db_record(Zone,Serial,Type) -> %ixfr
read_db_record(?DBStorage,Zone,Serial,Type).
read_db_record(ets,Zone,Serial,all) ->
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'>','$3',Serial},{'=<','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'>','$2',Serial},{'=<','$2',Zone#rpz.serial}],['$$']}]);
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'>','$3',Serial},{'=<','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'>','$2',Serial},{'=<','$2',Zone#rpz.serial}],['$$']}]);

read_db_record(ets,Zone,Serial,updated) ->
% io:fwrite(group_leader(),"Read updated records. Zone ~p Serial ~p ~n",[Zone,Serial]),
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'=<','$3',Serial},{'>=','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'=<','$2',Serial},{'>','$2',Zone#rpz.serial}],['$$']}]);
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'=<','$3',Serial},{'>=','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'=<','$2',Serial},{'>','$2',Zone#rpz.serial}],['$$']}]);


read_db_record(ets,Zone,Serial,new) ->
% io:fwrite(group_leader(),"Read expired records. Zone ~p Serial ~p ~n",[Zone,Serial]),
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'>','$2',Serial},{'>','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'==','$3',0},{'>','$2',Serial}],['$$']}]);
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'>','$2',Serial},{'>','$3',Zone#rpz.serial}],['$$']},{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'==','$3',0},{'>','$2',Serial}],['$$']}]);

read_db_record(ets,Zone,Serial,expired) ->
% io:fwrite(group_leader(),"Read expired records. Zone ~p Serial ~p ~n",[Zone,Serial]),
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'=<','$2',Serial},{'>=','$3',Serial},{'=<','$3',Zone#rpz.serial}],['$$']}]);
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'=<','$2',Serial},{'>=','$3',Serial},{'=<','$3',Zone#rpz.serial}],['$$']}]);


read_db_record(ets,Zone,_Serial,active) -> %All not expired
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'>','$3',Zone#rpz.serial},{'>=','$2',Zone#rpz.serial_ixfr}],['$$']},{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[{'==','$3',0},{'>=','$2',Zone#rpz.serial_ixfr}],['$$']}]);
ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'>','$3',Zone#rpz.serial},{'>=','$2',Zone#rpz.serial_ixfr}],['$$']},{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[{'==','$3',0},{'>=','$2',Zone#rpz.serial_ixfr}],['$$']}]);

read_db_record(mnesia,Zone,Serial,all) -> ok;
read_db_record(mnesia,Zone,Serial,updated) -> ok;
@@ -118,53 +118,47 @@ write_db_record(Zone,IOC,XFR) ->
{ok,0}.

write_db_record(ets,Zone,IOCs,axfr) ->
%TODO интеллектуальное обновление записи:
%запись уже заэкспайрилась - обновить serial и expiration time (потому что могли уже кому-то передать удаление записи) возможно в ключ нужно будет добавить версионность
%запись ежё действует - обновить expiration time
%добавить Serial в ключ? AXFR время обновления - полностью удаляет IXFR таблицу?
%Типа AXFR - полная ресинхронизация, которая делается редко, IXFR делается часто
CTime=erlang:system_time(seconds),
[ets:insert_new(rpz_ixfr_table, {{ioc,Zone#rpz.zone,IOC,Zone#rpz.serial},IOCExp}) || {IOC,IOCExp} <- IOCs, (IOCExp > CTime) or (IOCExp == 0)],
[ets:insert_new(rpz_ixfr_table, {{ioc,Zone#rpz.zone,IOC},Zone#rpz.serial,IOCExp}) || {IOC,IOCExp} <- IOCs, (IOCExp > CTime) or (IOCExp == 0)],
{ok,0}; %length(IOCs)

write_db_record(mnesia,Zone,{IOC,IOCExp},axfr) ->
{ok,0};

write_db_record(ets,Zone,IOCs,ixfr) ->
write_db_record(ets,Zone,IOCs,ixfr) when IOCs /= [] ->
CTime=erlang:system_time(seconds),
?logDebugMSG("Fetching zone ~p from ets~n",[Zone#rpz.zone_str]),
IOCDB=ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[],[{{'$1','$3'}}]}]),
IOCDB=ets:select(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[],[{{'$1','$3'}}]}]),
?logDebugMSG("Finding new or updated records~n",[]),
IOCNEW=ordsets:subtract(ordsets:from_list(IOCs),ordsets:from_list(IOCDB)),

% ?logDebugMSG("Update ets. New ~p, DB ~p, Delta ~p~n IOCs ~p~n IOCDB ~p~n IOCNEW ~p~n",[ordsets:size(IOCs),ordsets:size(IOCDB),ordsets:size(IOCNEW),IOCs,IOCDB,IOCNEW]),
?logDebugMSG("Update ets. New ~p, DB ~p, Delta ~p~n",[length(IOCs),length(IOCDB),ordsets:size(IOCNEW)]),
[update_db_record(?DBStorage,Zone#rpz.zone,Zone#rpz.serial,IOC,IOCExp,lists:keyfind(IOC,1,IOCDB),CTime) || {IOC,IOCExp} <- IOCNEW],
[update_db_record(?DBStorage,Zone#rpz.zone,Zone#rpz.serial,IOC,IOCExp,ets:lookup(rpz_ixfr_table, {ioc,Zone#rpz.zone,IOC}),CTime) || {IOC,IOCExp} <- IOCNEW],
{ok,ordsets:size(IOCNEW)};

write_db_record(ets,Zone,IOCs,ixfr) when IOCs == [] ->
?logDebugMSG("Zone ~p incremental request returned no new indicators~n",[Zone#rpz.zone_str]),
{ok,0};

write_db_record(mnesia,Zone,IOCs,ixfr) ->
{ok,0};

write_db_record(_DBStorage,_Zone,_IOCs,_XFR) ->
{ok,0}. %non cached zones

update_db_record(ets, Zone, Serial, IOC, IOCExp, false, CTime) when IOCExp > CTime ->
update_db_record(ets, Zone, Serial, IOC, IOCExp, [], CTime) when IOCExp > CTime ->
%?logDebugMSG("Update ~p ~p ~p ~p ~p ~n",[Serial, IOC, IOCExp, false, CTime]),
ets:insert_new(rpz_ixfr_table, {{ioc,Zone,IOC,Serial},IOCExp});
ets:insert_new(rpz_ixfr_table, {{ioc,Zone,IOC},Serial,IOCExp}); %insert for duplicate_bag

update_db_record(ets, Zone, Serial, IOC, IOCExp, [], CTime) when IOCExp =< CTime -> ok; % do not add new but expired indicators

update_db_record(ets, Zone, Serial, IOC, IOCExp, false, CTime) when IOCExp =< CTime -> ok; % do not add new but expired indicators
update_db_record(ets, Zone, Serial, IOC, IOCExp, [{ioc,_,_,OSerial,ExpTime}], CTime) when ExpTime < IOCExp, IOCExp >= CTime ->
ets:delete_object(rpz_ixfr_table,{{ioc,Zone,IOC},OSerial,ExpTime}),ets:insert_new(rpz_ixfr_table, {{ioc,Zone,IOC},OSerial,IOCExp});

update_db_record(ets, Zone, Serial, IOC, IOCExp, [{ioc,_,_,OSerial,ExpTime}], CTime) when IOCExp > 0, ExpTime == 0 ->
ets:select_delete(rpz_ixfr_table,[{{{ioc,Zone,IOC},'_','_'},[],[true]}]),ets:insert_new(rpz_ixfr_table, {{ioc,Zone,IOC},Serial,IOCExp});

update_db_record(ets, Zone, Serial, IOC, IOCExp, {_,ExpTime}, CTime) ->
%?logDebugMSG("Update ~p ~p ~p ~p ~p ~n",[Serial, IOC, IOCExp, ExpTime, CTime]),
case ExpTime of
ExpTime when ExpTime < IOCExp, IOCExp >= CTime ->
case ets:select(rpz_ixfr_table,[{{{ioc,Zone,IOC,'$3'},'_'},[],['$3']}]) of
[OSerial] -> ets:update_element(rpz_ixfr_table,{ioc,Zone,IOC,OSerial},{2,IOCExp}) %update expiration if expiration date was increased
end;
ExpTime when IOCExp > 0, ExpTime == 0 -> ets:select_delete(rpz_ixfr_table,[{{{ioc,Zone,IOC,'_'},'_'},[],[true]}]),ets:insert_new(rpz_ixfr_table, {{ioc,Zone,IOC,Serial},IOCExp}); %update serial and expiration if expired already
_ -> ok % Got 0 ExpTime but we have a record with a real Exp time. ?logDebugMSG("Bug in update ~p ~p ~p ~p ~p ~p ~n",[Zone, Serial, IOC, IOCExp, ExpTime, CTime])
end,
ok;
update_db_record(mnesia, Zone, Serial, IOC, IOCExp, Update, CTime) -> ok.

delete_old_db_record(Zone) ->
@@ -173,13 +167,13 @@ delete_old_db_record(Zone) ->

delete_old_db_record(ets, Zone) when Zone#rpz.serial == 42 ->
%?logDebugMSG("Removing IXFR zone ~p ~n",[Zone#rpz.zone_str]),
ets:match_delete(rpz_ixfr_table,{{ioc,Zone#rpz.zone,'_','_'},'_'}),
ets:match_delete(rpz_ixfr_table,{{ioc,Zone#rpz.zone,'_'},'_','_'}),
ets:match_delete(rpz_ixfr_table,{{ixfr_rpz_cfg,Zone#rpz.zone},'_','_','_','_'});

delete_old_db_record(ets, Zone) ->
NRbefore=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[],['true']}]),
ets:select_delete(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'_','$1'},'_'},[{'<','$1',Zone#rpz.serial}],[true]}]),
NRafter=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[],['true']}]),
NRbefore=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[],['true']}]),
ets:select_delete(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'_'},'$1','_'},[{'<','$1',Zone#rpz.serial}],[true]}]),
NRafter=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[],['true']}]),
if NRbefore /= NRafter -> ?logDebugMSG("Delete old records from zone ~p. before ~p after ~p ~n",[Zone#rpz.zone_str, NRbefore, NRafter]); true -> ok end;
delete_old_db_record(mnesia, Zone) ->
ok.
@@ -69,7 +69,7 @@ msg_CEF(301) -> "|000301|MGMT request denied|7|src=~s spt=~p proto=~p qname=~

msg_CEF(501) -> "|000501|Possible DDoS CVE-2004-0789|3|src=~s spt=~p proto=~p~n";

msg_CEF(999) -> "Not defined~n".
msg_CEF(_) -> "Not defined~n".

strs_to_binary(Strs) ->
strs_to_binary(Strs,[]).
@@ -238,9 +238,31 @@ split([H|T],Index)->
[[H|RH],RT].

%%%%
%%%% Unit tests
%%%% EUnit tests
%%%%
q_class_test() -> [
?assert(q_class(?C_IN) =:= "IN"),
?assert(q_class(42) =:= "42")
].
].

q_type_test() -> [
?assert(q_type(?T_CNAME) =:= "CNAME"),
?assert(q_type(42) =:= "42")
].

conv_to_Mb_test() -> [
?assert(conv_to_Mb(42) =:= <<"42/bytes">>),
?assert(conv_to_Mb(1536) =:= <<"1.50/KB">>),
?assert(conv_to_Mb(3221225472) =:= <<"3.00/GB">>)
].

msg_CEF_test() -> [
?assert(msg_CEF(138) =:= "|000138|Zone not found|7|src=~s spt=~p path=~p msg=~p~n"),
?assert(msg_CEF(424242) =:= "Not defined~n")
].


ip_to_bin_test() ->[
?assert(ip_to_bin("10.10.10.10") =:= <<10,10,10,10>>),
?assert(ip_to_bin("fc00::01") =:= <<16#fc00:16,0:16,0:16,0:16,0:16,0:16,0:16,1:16>>)
].
@@ -299,7 +299,7 @@ read_config3([],reload,Srv,Keys,Key_Groups,WhiteLists,Sources,RPZ) ->

WhiteLists_UPD = [ X || X <- WhiteLists_V, X#source.axfr_url /= (checkSrcRec(lists:keyfind(X#source.name,2,WhiteLists_C)))#source.axfr_url,lists:member(X#source.name, [ Z#source.name || Z <- WhiteLists_C ]) ],

Sources_UPD = [ X || X <- Sources_V, ((X#source.axfr_url /= (checkSrcRec(lists:keyfind(X#source.name,2,Sources_C)))#source.axfr_url) or (X#source.ixfr_url /= (checkSrcRec(lists:keyfind(X#source.name,2,Sources_C)))#source.ixfr_url)),lists:member(X#source.name, [ Z#source.name || Z <- Sources_C ]) ],
Sources_UPD = [ X || X <- Sources_V, ((X#source.axfr_url /= (checkSrcRec(lists:keyfind(X#source.name,2,Sources_C)))#source.axfr_url) or (X#source.ixfr_url /= (checkSrcRec(lists:keyfind(X#source.name,2,Sources_C)))#source.ixfr_url)) and (lists:member(X#source.name, [ Z#source.name || Z <- Sources_C ])) ],

[ ets:insert(cfg_table, {[source,X#source.name],X}) || X <- WhiteLists_N ++ Sources_N ++ WhiteLists_UPD ++ Sources_UPD ],

@@ -320,7 +320,7 @@ read_config3([],reload,Srv,Keys,Key_Groups,WhiteLists,Sources,RPZ) ->
[ ets:insert(cfg_table, {[rpz,X#rpz.zone],X#rpz.zone,X}) || X <- RPZ_V ],
[ ets:match_delete(rpz_hotcache_table,{{pkthotcache,X#rpz.zone,'_'},'_','_'}) || X <- RPZ_D ++ RPZ_UPD ],

ioc2rpz_db:clean_DB(RPZ_D ++ RPZ_UPD), %TODO check
ioc2rpz_db:clean_DB(RPZ_D), %TODO check % ++ RPZ_UPD - should be updated via standard AXFR update.

[ ets:update_element(cfg_table, [rpz,X#rpz.zone], [{3, X#rpz{status=notready}}]) || X <- RPZ_UPD ],

@@ -415,7 +415,7 @@ load_ixfr_zone_info(Zone) ->

load_ixfr_zone_info(ets,Zone) ->
CTime=ioc2rpz_fun:curr_serial(), %erlang:system_time(seconds),
case ioc2rpz_db:get_zone_info(Zone,ixfr) of %ets:match(rpz_ixfr_table,{{ixfr_rpz_cfg,Zone#rpz.zone},'$1','$2','$3'})
case ioc2rpz_db:get_zone_info(Zone,ixfr) of
[[_,Serial,Serial_IXFR,IXFR_Update_time]] when (IXFR_Update_time+Zone#rpz.ixfr_time)>CTime ->
ioc2rpz_fun:logMessage("Get IXFR zone ~p serial ~p status ready ~n",[Zone#rpz.zone_str,Serial_IXFR]),
[ready,Serial,Serial_IXFR,IXFR_Update_time];
@@ -493,7 +493,7 @@ update_zone_inc(Zone) ->
%io:fwrite(group_leader(),"Zone ~p IOC ~p ~n",[Zone#rpz.zone_str,IOC]),
Pid=self(),
ioc2rpz_fun:logMessage("Process PID ~p incremental update ~p started ~n",[Pid, Zone#rpz.zone_str]),
NRbefore=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[],['true']}]),
NRbefore=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[],['true']}]),
CTime=ioc2rpz_fun:curr_serial_60(), %erlang:system_time(seconds),
ioc2rpz_fun:logMessage("Updating zone ~p inc. Last IXFR update ~p seconds ago, last non-zero update ~p seconds ago~n",[Zone#rpz.zone_str,(CTime - Zone#rpz.ixfr_update_time),(CTime-Zone#rpz.ixfr_nz_update_time)]),
ets:update_element(cfg_table, [rpz,Zone#rpz.zone], [{3, Zone#rpz{status=updating, ixfr_update_time=CTime, pid=Pid}}]),
@@ -514,7 +514,7 @@ update_zone_inc(Zone) ->
?logDebugMSG("Rebuilding AXFR zone ~p. New IOCs ~p~n",[Zone#rpz.zone_str,NewIOCs]),
rebuild_axfr_zone(Zone#rpz{serial=CTime}),
?logDebugMSG("AXFR zone ~p was rebuilded~n",[Zone#rpz.zone_str]),
NRafter=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1','$2'},'$3'},[],['true']}]),
NRafter=ets:select_count(rpz_ixfr_table,[{{{ioc,Zone#rpz.zone,'$1'},'$2','$3'},[],['true']}]),
ioc2rpz_fun:logMessage("Zone ~p records before ~p after ~p. ~n",[Zone#rpz.zone_str, NRbefore, NRafter]),
ets:update_element(cfg_table, [rpz,Zone#rpz.zone], [{3, Zone#rpz{status=ready, serial=CTime, ixfr_update_time=CTime, ixfr_nz_update_time=CTime, pid=undefined, ioc_count=length(IOC)}}]),
ioc2rpz_db:delete_db_pkt(Zone),

0 comments on commit 999fe10

Please sign in to comment.
You can’t perform that action at this time.