X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/6cb6b7ede2d178e03fa817bc28474c175f5a93b9..0a9944546bc1cf591dfce10112a4385049909f02:/dnscore.pas?ds=inline

diff --git a/dnscore.pas b/dnscore.pas
index ef4c2f1..600581d 100755
--- a/dnscore.pas
+++ b/dnscore.pas
@@ -163,8 +163,7 @@ function makereversename(const binip:tbinip):string;
 procedure setstate_request_init(const name:string;var state:tdnsstate);
 
 //set up state for a foward lookup. A family value of AF_INET6 will give only
-//ipv6 results. Any other value will give ipv4 results in preference and ipv6
-//results if ipv4 results are not available;
+//ipv6 results. Any other value will give only ipv4 results
 procedure setstate_forward(const name:string;var state:tdnsstate;family:integer);
 
 procedure setstate_reverse(const binip:tbinip;var state:tdnsstate);
@@ -188,14 +187,27 @@ var
   dnsserverlist : tstringlist;
 //  currentdnsserverno : integer;
 
+
+//getcurrentsystemnameserver returns the nameserver the app should use and sets
+//id to the id of that nameserver. id should later be used to report how laggy
+//the servers response was and if it was timed out.
 function getcurrentsystemnameserver(var id:integer) :string;
+procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout
 
 //var
 //  unixnameservercache:string;
 { $endif}
 
 
-procedure reportlag(id:integer;lag:integer); //lag should be in microseconds and should be -1 to report a timeout
+{$ifdef linux}{$ifdef ipv6}
+function getv6localips:tbiniplist;
+procedure initpreferredmode;
+
+var
+  preferredmodeinited:boolean;
+
+{$endif}{$endif}
+
 var
   failurereason:string;
 
@@ -516,23 +528,7 @@ begin
 
     {no cnames found, no items of correct type found}
     if state.forwardfamily <> 0 then goto failure;
-{$ifdef ipv6}
-    if (state.requesttype = querytype_a) then begin
-      {v6 only: in case of forward, look for AAAA in alternative section}
-      for a := state.numrr1[0]+state.numrr1[1]+state.numrr1[2] to (state.numrr2-1) do begin
-        rrptemp := @state.rrdata[1+a*sizeof(trrpointer)];
-        rrtemp := rrptemp.p;
-        b := rrptemp.len;
-        if rrtemp.requesttype = querytype_aaaa then begin
-          setstate_return(rrptemp^,b,state);
-          exit;
-        end;
-      end;
-      {no AAAA's found in alternative, do a recursive lookup for them}
-      state.requesttype := querytype_aaaa;
-      goto recursed;
-    end;
-{$endif}
+
     goto failure;
 recursed:
     {here it needs recursed lookup}
@@ -703,6 +699,65 @@ begin
 
 end;
 
+
+
+{$ifdef linux}{$ifdef ipv6}
+function getv6localips:tbiniplist;
+var
+  t:textfile;
+  s,s2:string;
+  ip:tbinip;
+  a:integer;
+begin
+  result := biniplist_new;
+
+  assignfile(t,'/proc/net/if_inet6');
+  {$i-}reset(t);{$i+}
+  if ioresult <> 0 then exit; {none found, return empty list}
+
+  while not eof(t) do begin
+    readln(t,s);
+    s2 := '';
+    for a := 0 to 7 do begin
+      if (s2 <> '') then s2 := s2 + ':';
+      s2 := s2 + copy(s,(a shl 2)+1,4);
+    end;
+    ipstrtobin(s2,ip);
+    if ip.family <> 0 then biniplist_add(result,ip);
+  end;
+  closefile(t);
+end;
+
+procedure initpreferredmode;
+var
+  l:tbiniplist;
+  a:integer;
+  ip:tbinip;
+  ipmask_global,ipmask_6to4,ipmask_teredo:tbinip;
+
+begin
+  if preferredmodeinited then exit;
+  if useaf <> useaf_default then exit;
+  useaf := useaf_preferv4;
+  l := getv6localips;
+  ipstrtobin('2000::',ipmask_global);
+  ipstrtobin('2001::',ipmask_teredo);
+  ipstrtobin('2002::',ipmask_6to4);
+  {if there is any v6 IP which is globally routable and not 6to4 and not teredo, prefer v6}
+  for a := biniplist_getcount(l)-1 downto 0 do begin
+    ip := biniplist_get(l,a);
+    if not comparebinipmask(ip,ipmask_global,3) then continue;
+    if comparebinipmask(ip,ipmask_teredo,32) then continue;
+    if comparebinipmask(ip,ipmask_6to4,16) then continue;
+    useaf := useaf_preferv6;
+    preferredmodeinited := true;
+    exit;
+  end;
+end;
+
+{$endif}{$endif}
+
+
 {  quick and dirty description of dns packet structure to aid writing and
    understanding of parser code, refer to appropriate RFCs for proper specs
 - all words are network order