X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/6cb6b7ede2d178e03fa817bc28474c175f5a93b9..94dd0df9f67acf39e8e85e44ade8021a98c417a1:/dnssync.pas diff --git a/dnssync.pas b/dnssync.pas index 3632b29..a7ba714 100755 --- a/dnssync.pas +++ b/dnssync.pas @@ -25,6 +25,7 @@ interface sockets, fd_utils, {$endif} + lcorernd, sysutils; //convert a name to an IP @@ -44,14 +45,7 @@ function forwardlookuplist(name:string;timeout:integer):tbiniplist; //details as above function reverselookup(ip:tbinip;timeout:integer):string; -{$ifdef linux}{$ifdef ipv6} -function getv6localips:tbiniplist; -procedure initpreferredmode; -var - preferredmodeinited:boolean; - -{$endif}{$endif} const tswrap=$4000; @@ -61,8 +55,9 @@ const defaulttimeout=10000; const mintimeout=16; + toport='53'; + var - dnssyncserver:string; id:integer; sendquerytime:array[0..numsock-1] of integer; @@ -84,6 +79,7 @@ var numsockused:integer; fd:array[0..numsock-1] of integer; state:array[0..numsock-1] of tdnsstate; + toaddr:array[0..numsock-1] of tbinip; {$ifdef syncdnscore} @@ -122,10 +118,15 @@ begin result := false; if len = 0 then exit; {no packet} - if dnssyncserver <> '' then addr := dnssyncserver else addr := getcurrentsystemnameserver(id); - port := '53'; + if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(id); - makeinaddrv(ipstrtobinf(addr),port,inaddr); + {$ifdef ipv6}{$ifdef win32} + if toaddr[socknum].family = AF_INET6 then if (useaf = 0) then useaf := useaf_preferv6; + {$endif}{$endif} + + port := toport; + toaddr[socknum] := ipstrtobinf(addr); + makeinaddrv(toaddr[socknum],port,inaddr); sendto(fd[socknum],packet,len,0,inaddr,inaddrsize(inaddr)); sendquerytime[socknum] := getts; @@ -142,16 +143,17 @@ 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); + if overridednsserver <> '' then addr := overridednsserver else addr := getcurrentsystemnameserver(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; - inaddrtemp.inaddr.family := biniptemp.family; + if biniptemp.family = AF_INET6 then biniptemp := ipstrtobinf('::') else biniptemp := ipstrtobinf('0.0.0.0'); + 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 @@ -182,6 +184,12 @@ var 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:string; + begin if timeout < mintimeout then timeout := defaulttimeout; @@ -249,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; + if overridednsserver = '' then 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; @@ -260,7 +280,7 @@ begin currenttime := getts; - if dnssyncserver = '' then reportlag(id,-1); + if overridednsserver = '' then reportlag(id,-1); if (currenttime >= endtime) and ((not wrapmode) or (currenttime < starttime)) then begin exit; end else begin @@ -274,16 +294,6 @@ begin end; {$endif} -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; function forwardlookuplist(name:string;timeout:integer):tbiniplist; @@ -324,7 +334,7 @@ begin {$endif} begin {$ifdef syncdnscore} - {$ifdef linux}{$ifdef ipv6}initpreferredmode;{$endif}{$endif} + {$ifdef ipv6}initpreferredmode;{$endif} numsockused := 0; @@ -351,7 +361,7 @@ begin end else begin biniplist_addlist(result,state[0].resultlist); biniplist_addlist(result,state[1].resultlist); - {$endif} + {$endif} end; {$endif} end; @@ -383,62 +393,6 @@ begin {$endif} end; -{$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} - {$ifdef win32} var wsadata : twsadata;