25 |
sockets, |
sockets, |
26 |
fd_utils, |
fd_utils, |
27 |
{$endif} |
{$endif} |
28 |
|
lcorernd, |
29 |
sysutils; |
sysutils; |
30 |
|
|
31 |
//convert a name to an IP |
//convert a name to an IP |
45 |
//details as above |
//details as above |
46 |
function reverselookup(ip:tbinip;timeout:integer):string; |
function reverselookup(ip:tbinip;timeout:integer):string; |
47 |
|
|
|
{$ifdef linux}{$ifdef ipv6} |
|
|
function getv6localips:tbiniplist; |
|
|
procedure initpreferredmode; |
|
48 |
|
|
|
var |
|
|
preferredmodeinited:boolean; |
|
|
|
|
|
{$endif}{$endif} |
|
49 |
|
|
50 |
const |
const |
51 |
tswrap=$4000; |
tswrap=$4000; |
55 |
defaulttimeout=10000; |
defaulttimeout=10000; |
56 |
const mintimeout=16; |
const mintimeout=16; |
57 |
|
|
58 |
|
toport='53'; |
59 |
|
|
60 |
var |
var |
|
dnssyncserver:string; |
|
61 |
id:integer; |
id:integer; |
62 |
|
|
63 |
sendquerytime:array[0..numsock-1] of integer; |
sendquerytime:array[0..numsock-1] of integer; |
79 |
numsockused:integer; |
numsockused:integer; |
80 |
fd:array[0..numsock-1] of integer; |
fd:array[0..numsock-1] of integer; |
81 |
state:array[0..numsock-1] of tdnsstate; |
state:array[0..numsock-1] of tdnsstate; |
82 |
|
toaddr:array[0..numsock-1] of tbinip; |
83 |
|
|
84 |
{$ifdef syncdnscore} |
{$ifdef syncdnscore} |
85 |
|
|
118 |
result := false; |
result := false; |
119 |
if len = 0 then exit; {no packet} |
if len = 0 then exit; {no packet} |
120 |
|
|
121 |
if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id); |
if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id); |
122 |
port := '53'; |
|
123 |
|
{$ifdef ipv6}{$ifdef win32} |
124 |
|
if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6; |
125 |
|
{$endif}{$endif} |
126 |
|
|
127 |
makeinaddrv(ipstrtobinf(addr),port,inaddr); |
port := toport; |
128 |
|
toaddr[socknum] := ipstrtobinf(addr); |
129 |
|
makeinaddrv(toaddr[socknum],port,inaddr); |
130 |
|
|
131 |
sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr)); |
sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr)); |
132 |
sendquerytime[socknum] := getts; |
sendquerytime[socknum] := getts; |
143 |
//init both sockets smultaneously, always, so they get succesive fd's |
//init both sockets smultaneously, always, so they get succesive fd's |
144 |
if fd[0] > 0 then exit; |
if fd[0] > 0 then exit; |
145 |
|
|
146 |
if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id); |
if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id); |
147 |
//must get the DNS server here so we know to init v4 or v6 |
//must get the DNS server here so we know to init v4 or v6 |
148 |
|
|
|
fillchar(inaddrtemp,sizeof(inaddrtemp),0); |
|
149 |
ipstrtobin(addr,biniptemp); |
ipstrtobin(addr,biniptemp); |
|
if biniptemp.family = 0 then biniptemp.family := AF_INET; |
|
150 |
|
|
151 |
inaddrtemp.inaddr.family := biniptemp.family; |
if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0'); |
152 |
|
|
153 |
|
|
154 |
for a := 0 to numsockused-1 do begin |
for a := 0 to numsockused-1 do begin |
155 |
|
makeinaddrv(biniptemp,inttostr( 1024 + randominteger(65536 - 1024) ),inaddrtemp); |
156 |
|
|
157 |
fd[a] := Socket(biniptemp.family,SOCK_DGRAM,0); |
fd[a] := Socket(biniptemp.family,SOCK_DGRAM,0); |
158 |
|
|
159 |
If {$ifndef win32}Not{$endif} Bind(fd[a],inAddrtemp,inaddrsize(inaddrtemp)) Then begin |
If {$ifndef win32}Not{$endif} Bind(fd[a],inAddrtemp,inaddrsize(inaddrtemp)) Then begin |
184 |
finished:array[0..numsock-1] of boolean; |
finished:array[0..numsock-1] of boolean; |
185 |
a,b:integer; |
a,b:integer; |
186 |
|
|
187 |
|
Src : TInetSockAddrV; |
188 |
|
Srcx : {$ifdef win32}sockaddr_in{$else}TInetSockAddrV{$endif} absolute Src; |
189 |
|
SrcLen : Integer; |
190 |
|
fromip:tbinip; |
191 |
|
fromport:string; |
192 |
|
|
193 |
begin |
begin |
194 |
if timeout < mintimeout then timeout := defaulttimeout; |
if timeout < mintimeout then timeout := defaulttimeout; |
195 |
|
|
257 |
fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0); |
fillchar(state[socknum].recvpacket,sizeof(state[socknum].recvpacket),0); |
258 |
msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask); |
msectotimeval(lag,(currenttime-sendquerytime[socknum]) and tsmask); |
259 |
|
|
260 |
if dnssyncserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec); |
if overridednsserver = '' then reportlag(id,(lag.tv_sec*1000000)+lag.tv_usec); |
261 |
state[socknum].recvpacketlen := recv(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0); |
|
262 |
|
SrcLen := SizeOf(Src); |
263 |
|
state[socknum].recvpacketlen := recvfrom(fd[socknum],state[socknum].recvpacket, SizeOf(state[socknum].recvpacket),0,Srcx,SrcLen); |
264 |
|
|
265 |
|
if (state[socknum].recvpacketlen > 0) then begin |
266 |
|
fromip := inaddrvtobinip(Src); |
267 |
|
fromport := inttostr(htons(src.InAddr.port)); |
268 |
|
if ((not comparebinip(toaddr[socknum],fromip)) or (fromport <> toport)) then begin |
269 |
|
// writeln('dnssync received from wrong IP:port ',ipbintostr(fromip),'#',fromport); |
270 |
|
state[socknum].recvpacketlen := 0; |
271 |
|
end else begin |
272 |
state[socknum].parsepacket := true; |
state[socknum].parsepacket := true; |
273 |
needprocessing[socknum] := true; |
needprocessing[socknum] := true; |
274 |
end; |
end; |
275 |
end; |
end; |
276 |
|
end; |
277 |
|
end; |
278 |
if selectresult < 0 then exit; |
if selectresult < 0 then exit; |
279 |
if selectresult = 0 then begin |
if selectresult = 0 then begin |
280 |
|
|
281 |
currenttime := getts; |
currenttime := getts; |
282 |
|
|
283 |
if dnssyncserver = '' then reportlag(id,-1); |
if overridednsserver = '' then reportlag(id,-1); |
284 |
if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin |
if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin |
285 |
exit; |
exit; |
286 |
end else begin |
end else begin |
294 |
end; |
end; |
295 |
{$endif} |
{$endif} |
296 |
|
|
|
procedure addipsoffamily(var l:tbiniplist;const l2:tbiniplist;family:integer); |
|
|
var |
|
|
a:integer; |
|
|
biniptemp:tbinip; |
|
|
begin |
|
|
for a := biniplist_getcount(l2)-1 downto 0 do begin |
|
|
biniptemp := biniplist_get(l2,a); |
|
|
if (biniptemp.family = family) then biniplist_add(l,biniptemp); |
|
|
end; |
|
|
end; |
|
297 |
|
|
298 |
|
|
299 |
function forwardlookuplist(name:string;timeout:integer):tbiniplist; |
function forwardlookuplist(name:string;timeout:integer):tbiniplist; |
334 |
{$endif} |
{$endif} |
335 |
begin |
begin |
336 |
{$ifdef syncdnscore} |
{$ifdef syncdnscore} |
337 |
{$ifdef linux}{$ifdef ipv6}initpreferredmode;{$endif}{$endif} |
{$ifdef ipv6}initpreferredmode;{$endif} |
338 |
|
|
339 |
numsockused := 0; |
numsockused := 0; |
340 |
|
|
393 |
{$endif} |
{$endif} |
394 |
end; |
end; |
395 |
|
|
|
{$ifdef linux}{$ifdef ipv6}{$ifdef syncdnscore} |
|
|
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}{$endif} |
|
|
|
|
396 |
{$ifdef win32} |
{$ifdef win32} |
397 |
var |
var |
398 |
wsadata : twsadata; |
wsadata : twsadata; |