removed use of global vars in dnssync, should be reentrant safe
[lcore.git] / dnssync.pas
index 9a0c2c1cc4cd88bfb9d7ae874f26291865339afc..d037a68ea9cc350bee1ca33d95cbd95e770efcce 100644 (file)
@@ -58,10 +58,6 @@ const
 \r
   toport='53';\r
 \r
-var\r
-  id:integer;\r
-\r
-  sendquerytime:array[0..numsock-1] of integer;\r
 implementation\r
 \r
 {$ifdef win32}\r
@@ -77,11 +73,7 @@ implementation
 \r
 \r
 {$ifdef syncdnscore}\r
-var\r
-  numsockused:integer;\r
-  fd:array[0..numsock-1] of integer;\r
-  state:array[0..numsock-1] of tdnsstate;\r
-  toaddr:array[0..numsock-1] of tbinip;\r
+\r
 \r
 {$ifdef win32}\r
   const\r
@@ -107,45 +99,43 @@ begin
 end;\r
 \r
 \r
-function sendquery(socknum:integer;const packet:tdnspacket;len:integer):boolean;\r
+type tdnsstatearr=array[0..numsock-1] of tdnsstate;\r
+\r
+procedure resolveloop(timeout:integer;var state:tdnsstatearr;numsockused:integer);\r
 var\r
-  ip       : tbinip;\r
-  port       : ansistring;\r
-  inaddr     : TInetSockAddrV;\r
-begin\r
-{  writeln('sendquery ',decodename(state.packet,state.packetlen,12,0,a),' ',state.requesttype);}\r
-  result := false;\r
-  if len = 0 then exit; {no packet}\r
+  selectresult   : integer;\r
+  fds            : fdset;\r
 \r
-  ip := getcurrentsystemnameserverbin(id);\r
+  endtime      : longint;\r
+  starttime    : longint;\r
+  wrapmode     : boolean;\r
+  currenttime  : integer;\r
 \r
-  {$ifdef ipv6}{$ifdef win32}\r
-  if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6;\r
-  {$endif}{$endif}\r
+  lag            : ttimeval;\r
+  selecttimeout         : ttimeval;\r
+  socknum:integer;\r
+  needprocessing:array[0..numsock-1] of boolean;\r
+  finished:array[0..numsock-1] of boolean;\r
+  a,b:integer;\r
 \r
-  port := toport;\r
-  toaddr[socknum] := ip;\r
-  makeinaddrv(toaddr[socknum],port,inaddr);\r
+  Src    : TInetSockAddrV;\r
+  Srcx   : {$ifdef win32}sockaddr_in{$else}TInetSockAddrV{$endif} absolute Src;\r
+  SrcLen : Integer;\r
+  fromip:tbinip;\r
+  fromport:ansistring;\r
+\r
+  fd:array[0..numsock-1] of integer;\r
+  toaddr:array[0..numsock-1] of tbinip;\r
+  id:integer;\r
+  sendquerytime:array[0..numsock-1] of integer;\r
 \r
-  sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));\r
-  sendquerytime[socknum] := getts;\r
-  result := true;\r
-end;\r
 \r
 procedure setupsocket;\r
 var\r
   inAddrtemp : TInetSockAddrV;\r
-  a:integer;\r
   biniptemp:tbinip;\r
-\r
+  a:integer;\r
 begin\r
-  //init both sockets smultaneously, always, so they get succesive fd's\r
-\r
-  {recreate sockets every time, reusing them will fail (hang) if the nameserver is changed\r
-  also changing the nameserver can't possibly work}\r
-  {if fd[0] > 0 then exit;}\r
-  for a := 0 to numsock-1 do if (fd[a] > 0) then closesocket(fd[a]);\r
-\r
   biniptemp := getcurrentsystemnameserverbin(id);\r
   //must get the DNS server here so we know to init v4 or v6\r
 \r
@@ -167,42 +157,53 @@ begin
   end;\r
 end;\r
 \r
-procedure resolveloop(timeout:integer);\r
+procedure cleanupsockets;\r
 var\r
-  selectresult   : integer;\r
-  fds            : fdset;\r
+  a:integer;\r
+begin\r
+  for a := 0 to numsockused-1 do closesocket(fd[a]);\r
+end;\r
 \r
-  endtime      : longint;\r
-  starttime    : longint;\r
-  wrapmode     : boolean;\r
-  currenttime  : integer;\r
+function sendquery(socknum:integer;const packet:tdnspacket;len:integer):boolean;\r
+var\r
+  ip       : tbinip;\r
+  port       : ansistring;\r
+  inaddr     : TInetSockAddrV;\r
+begin\r
+{  writeln('sendquery ',decodename(state.packet,state.packetlen,12,0,a),' ',state.requesttype);}\r
+  result := false;\r
+  if len = 0 then exit; {no packet}\r
 \r
-  lag            : ttimeval;\r
-  selecttimeout         : ttimeval;\r
-  socknum:integer;\r
-  needprocessing:array[0..numsock-1] of boolean;\r
-  finished:array[0..numsock-1] of boolean;\r
-  a,b:integer;\r
+  ip := getcurrentsystemnameserverbin(id);\r
 \r
-  Src    : TInetSockAddrV;\r
-  Srcx   : {$ifdef win32}sockaddr_in{$else}TInetSockAddrV{$endif} absolute Src;\r
-  SrcLen : Integer;\r
-  fromip:tbinip;\r
-  fromport:ansistring;\r
+  {$ifdef ipv6}{$ifdef win32}\r
+  if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6;\r
+  {$endif}{$endif}\r
+\r
+  port := toport;\r
+  toaddr[socknum] := ip;\r
+  makeinaddrv(toaddr[socknum],port,inaddr);\r
+\r
+  sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));\r
+  sendquerytime[socknum] := getts;\r
+  result := true;\r
+end;\r
 \r
 begin\r
   if timeout < mintimeout then timeout := defaulttimeout;\r
 \r
-    starttime := getts;\r
-    endtime := starttime + timeout;\r
-    if (endtime and tswrap)=0 then begin\r
-      wrapmode := false;\r
-    end else begin\r
-      wrapmode := true;\r
-    end;\r
-    endtime := endtime and tsmask;\r
+  starttime := getts;\r
+  endtime := starttime + timeout;\r
+  if (endtime and tswrap)=0 then begin\r
+    wrapmode := false;\r
+  end else begin\r
+    wrapmode := true;\r
+  end;\r
+  endtime := endtime and tsmask;\r
 \r
   setupsocket;\r
+\r
+\r
   for socknum := 0 to numsockused-1 do begin\r
     needprocessing[socknum] := true;\r
     finished[socknum] := false;\r
@@ -223,6 +224,7 @@ begin
             if finished[a] then inc(b);\r
           end;\r
           if (b = numsockused) then begin\r
+            cleanupsockets;\r
             exit;\r
           end;\r
           //onrequestdone(self,0);\r
@@ -282,6 +284,7 @@ begin
 \r
       reportlag(id,-1);\r
       if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin\r
+        cleanupsockets;\r
         exit;\r
       end else begin\r
         //resend\r
@@ -302,6 +305,10 @@ var
   a:integer;\r
   biniptemp:tbinip;\r
   l:tbiniplist;\r
+\r
+  numsockused:integer;\r
+  state:tdnsstatearr;\r
+\r
 begin\r
   ipstrtobin(name,biniptemp);\r
   if biniptemp.family <> 0 then begin\r
@@ -350,7 +357,7 @@ begin
     end;\r
     {$endif}\r
 \r
-    resolveloop(timeout);\r
+    resolveloop(timeout,state,numsockused);\r
 \r
     if (numsockused = 1) then begin\r
       biniplist_addlist(result,state[0].resultlist);\r
@@ -378,6 +385,8 @@ end;
 function reverselookup(ip:tbinip;timeout:integer):ansistring;\r
 var\r
   dummy : integer;\r
+  numsockused:integer;\r
+  state:tdnsstatearr;\r
 begin\r
   {$ifdef win32}\r
     if usewindns then begin\r
@@ -388,7 +397,7 @@ begin
   {$ifdef syncdnscore}\r
   setstate_reverse(ip,state[0]);\r
   numsockused := 1;\r
-  resolveloop(timeout);\r
+  resolveloop(timeout,state,numsockused);\r
   result := state[0].resultstr;\r
   {$endif}\r
 end;\r