sockets,\r
fd_utils,\r
{$endif}\r
- sysutils;\r
+ lcorernd,\r
+ sysutils,\r
+ ltimevalstuff;\r
\r
//convert a name to an IP\r
//will return v4 or v6 depending on what seems favorable, or manual preference setting\r
//details as above\r
function reverselookup(ip:tbinip;timeout:integer):string;\r
\r
-{$ifdef linux}{$ifdef ipv6}\r
-function getv6localips:tbiniplist;\r
-procedure initpreferredmode;\r
\r
-var\r
- preferredmodeinited:boolean;\r
-\r
-{$endif}{$endif}\r
\r
const\r
tswrap=$4000;\r
defaulttimeout=10000;\r
const mintimeout=16;\r
\r
+ toport='53';\r
+\r
var\r
- dnssyncserver:string;\r
id:integer;\r
\r
sendquerytime:array[0..numsock-1] of integer;\r
{$endif}\r
\r
{$i unixstuff.inc}\r
-{$i ltimevalstuff.inc}\r
\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
{$ifdef syncdnscore}\r
\r
result := false;\r
if len = 0 then exit; {no packet}\r
\r
- if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id);\r
- port := '53';\r
+ if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id);\r
\r
- makeinaddrv(ipstrtobinf(addr),port,inaddr);\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] := ipstrtobinf(addr);\r
+ makeinaddrv(toaddr[socknum],port,inaddr);\r
\r
sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr));\r
sendquerytime[socknum] := getts;\r
//init both sockets smultaneously, always, so they get succesive fd's\r
if fd[0] > 0 then exit;\r
\r
- if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id);\r
+ if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id);\r
//must get the DNS server here so we know to init v4 or v6\r
\r
- fillchar(inaddrtemp,sizeof(inaddrtemp),0);\r
ipstrtobin(addr,biniptemp);\r
- if biniptemp.family = 0 then biniptemp.family := AF_INET;\r
\r
- inaddrtemp.inaddr.family := biniptemp.family;\r
+ if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0');\r
+\r
\r
for a := 0 to numsockused-1 do begin\r
+ makeinaddrv(biniptemp,inttostr( 1024 + randominteger(65536 - 1024) ),inaddrtemp);\r
+\r
fd[a] := Socket(biniptemp.family,SOCK_DGRAM,0);\r
\r
If {$ifndef win32}Not{$endif} Bind(fd[a],inAddrtemp,inaddrsize(inaddrtemp)) Then begin\r
finished:array[0..numsock-1] of boolean;\r
a,b:integer;\r
\r
+ Src : TInetSockAddrV;\r
+ Srcx : {$ifdef win32}sockaddr_in{$else}TInetSockAddrV{$endif} absolute Src;\r
+ SrcLen : Integer;\r
+ fromip:tbinip;\r
+ fromport:string;\r
+\r
begin\r
if timeout < mintimeout then timeout := defaulttimeout;\r
\r
fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0);\r
msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask);\r
\r
- if dnssyncserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);\r
- state[socknum].recvpacketlen := recv(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0);\r
- state[socknum].parsepacket := true;\r
- needprocessing[socknum] := true;\r
+ if overridednsserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec);\r
+\r
+ SrcLen := SizeOf(Src);\r
+ state[socknum].recvpacketlen := recvfrom(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0,Srcx,SrcLen);\r
+\r
+ if (state[socknum].recvpacketlen > 0) then begin\r
+ fromip := inaddrvtobinip(Src);\r
+ fromport := inttostr(htons(src.InAddr.port));\r
+ if ((not comparebinip(toaddr[socknum],fromip)) or (fromport <> toport)) then begin\r
+// writeln('dnssync received from wrong IP:port ',ipbintostr(fromip),'#',fromport);\r
+ state[socknum].recvpacketlen := 0;\r
+ end else begin\r
+ state[socknum].parsepacket := true;\r
+ needprocessing[socknum] := true;\r
+ end;\r
+ end;\r
end;\r
end;\r
if selectresult < 0 then exit;\r
\r
currenttime := getts;\r
\r
- if dnssyncserver = '' then reportlag(id,-1);\r
+ if overridednsserver = '' then reportlag(id,-1);\r
if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin\r
exit;\r
end else begin\r
end;\r
{$endif}\r
\r
-procedure addipsoffamily(var l:tbiniplist;const l2:tbiniplist;family:integer);\r
-var\r
- a:integer;\r
- biniptemp:tbinip;\r
-begin\r
- for a := biniplist_getcount(l2)-1 downto 0 do begin\r
- biniptemp := biniplist_get(l2,a);\r
- if (biniptemp.family = family) then biniplist_add(l,biniptemp);\r
- end;\r
-end;\r
\r
\r
function forwardlookuplist(name:string;timeout:integer):tbiniplist;\r
{$endif}\r
begin\r
{$ifdef syncdnscore}\r
- {$ifdef linux}{$ifdef ipv6}initpreferredmode;{$endif}{$endif}\r
+ {$ifdef ipv6}initpreferredmode;{$endif}\r
\r
numsockused := 0;\r
\r
end else begin\r
biniplist_addlist(result,state[0].resultlist);\r
biniplist_addlist(result,state[1].resultlist);\r
- {$endif} \r
+ {$endif}\r
end;\r
{$endif}\r
end;\r
{$endif}\r
end;\r
\r
-{$ifdef linux}{$ifdef ipv6}{$ifdef syncdnscore}\r
-function getv6localips:tbiniplist;\r
-var\r
- t:textfile;\r
- s,s2:string;\r
- ip:tbinip;\r
- a:integer;\r
-begin\r
- result := biniplist_new;\r
-\r
- assignfile(t,'/proc/net/if_inet6');\r
- {$i-}reset(t);{$i+}\r
- if ioresult <> 0 then exit; {none found, return empty list}\r
-\r
- while not eof(t) do begin\r
- readln(t,s);\r
- s2 := '';\r
- for a := 0 to 7 do begin\r
- if (s2 <> '') then s2 := s2 + ':';\r
- s2 := s2 + copy(s,(a shl 2)+1,4);\r
- end;\r
- ipstrtobin(s2,ip);\r
- if ip.family <> 0 then biniplist_add(result,ip);\r
- end;\r
- closefile(t);\r
-end;\r
-\r
-procedure initpreferredmode;\r
-var\r
- l:tbiniplist;\r
- a:integer;\r
- ip:tbinip;\r
- ipmask_global,ipmask_6to4,ipmask_teredo:tbinip;\r
-\r
-begin\r
- if preferredmodeinited then exit;\r
- if useaf <> useaf_default then exit;\r
- useaf := useaf_preferv4;\r
- l := getv6localips;\r
- ipstrtobin('2000::',ipmask_global);\r
- ipstrtobin('2001::',ipmask_teredo);\r
- ipstrtobin('2002::',ipmask_6to4);\r
- {if there is any v6 IP which is globally routable and not 6to4 and not teredo, prefer v6}\r
- for a := biniplist_getcount(l)-1 downto 0 do begin\r
- ip := biniplist_get(l,a);\r
- if not comparebinipmask(ip,ipmask_global,3) then continue;\r
- if comparebinipmask(ip,ipmask_teredo,32) then continue;\r
- if comparebinipmask(ip,ipmask_6to4,16) then continue;\r
- useaf := useaf_preferv6;\r
- preferredmodeinited := true;\r
- exit;\r
- end;\r
-end;\r
-\r
-{$endif}{$endif}{$endif}\r
-\r
{$ifdef win32}\r
var\r
wsadata : twsadata;\r