--- lftp-3.3.5/src/resource.cc.bz173276 2005-11-08 02:21:19.000000000 -0500 +++ lftp-3.3.5/src/resource.cc 2005-12-21 13:44:59.000000000 -0500 @@ -338,10 +338,12 @@ res_cache_enable("dns:cache-enable", "yes", ResMgr::BoolValidate,0), res_cache_expire("dns:cache-expire", "1h", ResMgr::TimeIntervalValidate,0), res_cache_size ("dns:cache-size", "256", ResMgr::UNumberValidate,ResMgr::NoClosure), - res_timeout ("dns:fatal-timeout","0", ResMgr::UNumberValidate,0), + res_timeout ("dns:fatal-timeout","0", ResMgr::TimeIntervalValidate,0), res_order ("dns:order", DEFAULT_ORDER, OrderValidate,0), res_query_srv ("dns:SRV-query", "no", ResMgr::BoolValidate,0), - res_use_fork ("dns:use-fork", "yes", ResMgr::BoolValidate,ResMgr::NoClosure); + res_use_fork ("dns:use-fork", "yes", ResMgr::BoolValidate,ResMgr::NoClosure), + res_use_first ("dns:use-first-address", "yes", ResMgr::BoolValidate,ResMgr::NoClosure), + res_n_attempts ("dns:max-retries", "1000", ResMgr::UNumberValidate,0); static ResDecl fish_shell ("fish:shell", "/bin/sh", 0,0), --- lftp-3.3.5/src/Resolver.cc.bz173276 2005-11-08 01:17:11.000000000 -0500 +++ lftp-3.3.5/src/Resolver.cc 2005-12-21 13:54:41.000000000 -0500 @@ -505,6 +505,8 @@ time_t try_time; unsigned char answer[0x1000]; char *srv_name=string_alloca(strlen(service)+1+strlen(tproto)+1+strlen(hostname)+1); + int retries=0; + int max_retries=ResMgr::Query("dns:max-retries",hostname); sprintf(srv_name,"_%s._%s.%s",service,tproto,hostname); int len; @@ -523,6 +525,8 @@ #ifdef HAVE_H_ERRNO if(h_errno!=TRY_AGAIN) return; + if(++retries>=max_retries && max_retries) + return; time_t t=time(0); if(t-try_time<5) sleep(5-(t-try_time)); @@ -682,6 +686,10 @@ time_t try_time; int af_index=0; int af_order[16]; + int af_tries[16]; + int af_try=0, af_tried=0; + int dns_use_first =ResMgr::QueryBool("dns:use-first-address",name), + dns_n_attempts=ResMgr::Query("dns:max-retries",name); const char *order=ResMgr::Query("dns:order",name); @@ -698,6 +706,8 @@ } ParseOrder(order,af_order); + + memset(af_tries, 0, sizeof(af_tries)); for(;;) { @@ -778,8 +788,24 @@ #else // !HAVE_GETADDRINFO int af=af_order[af_index]; + if(af==-1) - break; + { + if((timeout == 0) && (af_tried == 0)) + break; + else + { + af_index = 0; + af_tried = 0; + af = af_order[af_index]; + } + } + + if ( af_tries [ af_index ] != -1 ) + { + if( (dns_n_attempts > 0) && ( af_tries [ af_index ] > dns_n_attempts) ) + break; + ++af_tries[ af_index ]; struct hostent *ha; # if defined(HAVE_GETIPNODEBYNAME) @@ -801,12 +827,19 @@ } # endif - if(ha) + af_tried = 1; + + if ( ha ) { const char * const *a; for(a=ha->h_addr_list; *a; a++) - AddAddress(ha->h_addrtype, *a, ha->h_length); - af_index++; + { + AddAddress(ha->h_addrtype, *a, ha->h_length); + af_tries[ af_index ] = -1; + } + if( (af_tries[ af_index ] == -1) && dns_use_first ) + return; + af_index++; # if defined(HAVE_GETIPNODEBYNAME) freehostent(ha); # endif @@ -825,14 +858,30 @@ error=_("Host name lookup failure"); # endif } - af_index++; - continue; // try other address families + af_tries[ af_index ] = -1; } + } /* af_tries[ af_index ] != -1 */ + #endif /* HAVE_GETADDRINFO */ - time_t t; - if((t=time(0))-try_time<5) - sleep(5-(t-try_time)); + time_t t = time(0); + if( timeout && (( t - start_time ) >= (timeout - 1)) ) + { + return; + }else + { + af_try = (af_order[af_index+1] == -1) ? 0 : ((af_index + 1) & 0xf); + if( (af_tries[ af_try ] != 0) || (af_tried == 0)) + { + if( timeout == 0 ) + { + if((t-try_time)<5) + sleep(5-(t-try_time)); + }else + sleep(1); + } + af_index++; + } } } @@ -896,7 +945,7 @@ void Resolver::Reconfig(const char *name) { - timeout = ResMgr::Query("dns:fatal-timeout",hostname); + timeout = TimeInterval(ResMgr::Query("dns:fatal-timeout",hostname)); if(!name || strncmp(name,"dns:",4)) return; if(cache) --- lftp-3.3.5/doc/lftp.1.bz173276 2005-12-02 02:23:31.000000000 -0500 +++ lftp-3.3.5/doc/lftp.1 2005-12-21 13:20:24.000000000 -0500 @@ -919,6 +919,20 @@ .BR dns:use-fork \ (boolean) if true, lftp will fork before resolving host address. Default is true. .TP +.BR dns:use-first-address \ (boolean) +If true (the default), lftp will use the first address returned by a host name lookup; +if false, lftp will continue trying to find addresses of each address family +in dns:order until an address of each family is found, is authoritatively +known not to exist (as opposed to servers not being contactable), or the +dns:fatal-timeout (if any) expires. +Setting this to true will make lftp use the first available address for a name. +.TP +.BR dns:max-retries \ (number) +If zero, (the default), there is no limit on the number of times lftp will try +to lookup an address . +If > 0, lftp will try only this number of times to look up an address of each +address family in dns:order . +.TP .BR file:charset \ (string) local character set. It is set from current locale initially. .TP