X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/d53fe26eaac895d1e7a0ba2b2b8965cf77932de8..096e05689a95dc55ef9f554978c5ea3f263bc919:/dnssync.pas?ds=inline

diff --git a/dnssync.pas b/dnssync.pas
old mode 100755
new mode 100644
index b682acf..9a0c2c1
--- a/dnssync.pas
+++ b/dnssync.pas
@@ -25,24 +25,26 @@ interface
       sockets,
       fd_utils,
     {$endif}
-    sysutils;
+    lcorernd,
+    sysutils,
+    ltimevalstuff;
 
 //convert a name to an IP
 //will return v4 or v6 depending on what seems favorable, or manual preference setting
 //on error the binip will have a family of 0 (other fiels are also currently
 //zeroed out but may be used for further error information in future)
 //timeout is in miliseconds, it is ignored when using windows dns
-function forwardlookup(name:string;timeout:integer):tbinip;
+function forwardlookup(name:ansistring;timeout:integer):tbinip;
 
 //convert a name to a list of all IP's returned
 //this returns both v4 and v6 IP's, or possibly only v4 or v6, depending on settings
 //on error, returns an empty list
-function forwardlookuplist(name:string;timeout:integer):tbiniplist;
+function forwardlookuplist(name:ansistring;timeout:integer):tbiniplist;
 
 
 //convert an IP to a name, on error a null string will be returned, other
 //details as above
-function reverselookup(ip:tbinip;timeout:integer):string;
+function reverselookup(ip:tbinip;timeout:integer):ansistring;
 
 
 
@@ -54,8 +56,9 @@ const
   defaulttimeout=10000;
   const mintimeout=16;
 
+  toport='53';
+
 var
-  dnssyncserver:string;
   id:integer;
 
   sendquerytime:array[0..numsock-1] of integer;
@@ -71,14 +74,14 @@ implementation
 {$endif}
 
 {$i unixstuff.inc}
-{$i ltimevalstuff.inc}
 
+
+{$ifdef syncdnscore}
 var
   numsockused:integer;
   fd:array[0..numsock-1] of integer;
   state:array[0..numsock-1] of tdnsstate;
-
-{$ifdef syncdnscore}
+  toaddr:array[0..numsock-1] of tbinip;
 
 {$ifdef win32}
   const
@@ -106,19 +109,23 @@ end;
 
 function sendquery(socknum:integer;const packet:tdnspacket;len:integer):boolean;
 var
-  a:integer;
-  addr       : string;
-  port       : string;
+  ip       : tbinip;
+  port       : ansistring;
   inaddr     : TInetSockAddrV;
 begin
 {  writeln('sendquery ',decodename(state.packet,state.packetlen,12,0,a),' ',state.requesttype);}
   result := false;
   if len = 0 then exit; {no packet}
 
-  if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id);
-  port := '53';
+  ip := getcurrentsystemnameserverbin(id);
+
+  {$ifdef ipv6}{$ifdef win32}
+  if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6;
+  {$endif}{$endif}
 
-  makeinaddrv(ipstrtobinf(addr),port,inaddr);
+  port := toport;
+  toaddr[socknum] := ip;
+  makeinaddrv(toaddr[socknum],port,inaddr);
 
   sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));
   sendquerytime[socknum] := getts;
@@ -130,21 +137,24 @@ var
   inAddrtemp : TInetSockAddrV;
   a:integer;
   biniptemp:tbinip;
-  addr:string;
+
 begin
   //init both sockets smultaneously, always, so they get succesive fd's
-  if fd[0] > 0 then exit;
 
-  if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id);
+  {recreate sockets every time, reusing them will fail (hang) if the nameserver is changed
+  also changing the nameserver can't possibly work}
+  {if fd[0] > 0 then exit;}
+  for a := 0 to numsock-1 do if (fd[a] > 0) then closesocket(fd[a]);
+
+  biniptemp := getcurrentsystemnameserverbin(id);
   //must get the DNS server here so we know to init v4 or v6
 
-  fillchar(inaddrtemp,sizeof(inaddrtemp),0);
-  ipstrtobin(addr,biniptemp);
-  if biniptemp.family = 0 then biniptemp.family := AF_INET;
+  if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0');
 
-  inaddrtemp.inaddr.family := biniptemp.family;
 
   for a := 0 to numsockused-1 do begin
+    makeinaddrv(biniptemp,inttostr( 1024 + randominteger(65536 - 1024) ),inaddrtemp);
+
     fd[a] := Socket(biniptemp.family,SOCK_DGRAM,0);
 
     If {$ifndef win32}Not{$endif} Bind(fd[a],inAddrtemp,inaddrsize(inaddrtemp)) Then begin
@@ -168,13 +178,18 @@ var
   currenttime  : integer;
 
   lag            : ttimeval;
-  currenttimeout : ttimeval;
   selecttimeout	 : ttimeval;
   socknum:integer;
   needprocessing:array[0..numsock-1] of boolean;
   finished:array[0..numsock-1] of boolean;
   a,b:integer;
 
+  Src    : TInetSockAddrV;
+  Srcx   : {$ifdef win32}sockaddr_in{$else}TInetSockAddrV{$endif} absolute Src;
+  SrcLen : Integer;
+  fromip:tbinip;
+  fromport:ansistring;
+
 begin
   if timeout < mintimeout then timeout := defaulttimeout;
 
@@ -242,10 +257,22 @@ begin
         fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0);
         msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask);
 
-        if dnssyncserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);
-        state[socknum].recvpacketlen := recv(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0);
-        state[socknum].parsepacket := true;
-        needprocessing[socknum] := true;
+        reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);
+
+        SrcLen := SizeOf(Src);
+        state[socknum].recvpacketlen := recvfrom(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0,Srcx,SrcLen);
+
+        if (state[socknum].recvpacketlen > 0) then begin
+          fromip := inaddrvtobinip(Src);
+          fromport := inttostr(htons(src.InAddr.port));
+          if ((not comparebinip(toaddr[socknum],fromip)) or (fromport <> toport)) then begin
+//            writeln('dnssync received from wrong IP:port ',ipbintostr(fromip),'#',fromport);
+            state[socknum].recvpacketlen := 0;
+          end else begin
+            state[socknum].parsepacket := true;
+            needprocessing[socknum] := true;
+          end;
+        end;
       end;
     end;
     if selectresult < 0 then exit;
@@ -253,7 +280,7 @@ begin
 
       currenttime := getts;
 
-      if dnssyncserver = '' then reportlag(id,-1);
+      reportlag(id,-1);
       if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin
         exit;
       end else begin
@@ -269,10 +296,10 @@ end;
 
 
 
-function forwardlookuplist(name:string;timeout:integer):tbiniplist;
+function forwardlookuplist(name:ansistring;timeout:integer):tbiniplist;
 var
   dummy : integer;
-  a,b:integer;
+  a:integer;
   biniptemp:tbinip;
   l:tbiniplist;
 begin
@@ -307,7 +334,7 @@ begin
   {$endif}
   begin
   {$ifdef syncdnscore}
-    {$ifdef linux}{$ifdef ipv6}initpreferredmode;{$endif}{$endif}
+    {$ifdef ipv6}initpreferredmode;{$endif}
 
     numsockused := 0;
 
@@ -334,13 +361,13 @@ begin
     end else begin
       biniplist_addlist(result,state[0].resultlist);
       biniplist_addlist(result,state[1].resultlist);
-    {$endif}  
+    {$endif}
     end;
     {$endif}
   end;
 end;
 
-function forwardlookup(name:string;timeout:integer):tbinip;
+function forwardlookup(name:ansistring;timeout:integer):tbinip;
 var
   listtemp:tbiniplist;
 begin
@@ -348,7 +375,7 @@ begin
   result := biniplist_get(listtemp,0);
 end;
 
-function reverselookup(ip:tbinip;timeout:integer):string;
+function reverselookup(ip:tbinip;timeout:integer):ansistring;
 var
   dummy : integer;
 begin