diff --git a/core/sip/resolver.cpp b/core/sip/resolver.cpp index 03bc2c15..9828c837 100644 --- a/core/sip/resolver.cpp +++ b/core/sip/resolver.cpp @@ -44,6 +44,13 @@ using std::list; #include "log.h" +// Maximum number of SRV entries +// within a cache entry +// +// (the limit is the # bits in dns_handle::srv_used) +#define MAX_SRV_RR (sizeof(unsigned int)*8) + + struct ip_entry : public dns_base_entry { @@ -116,6 +123,7 @@ int dns_srv_entry::next_ip(dns_handle* h, sockaddr_storage* sa) if(h->srv_e) dec_ref(h->srv_e); h->srv_e = this; h->srv_n = 0; + h->srv_used = 0; } else if(h->ip_n != -1){ ((sockaddr_in*)sa)->sin_port = h->port; @@ -138,26 +146,31 @@ int dns_srv_entry::next_ip(dns_handle* h, sockaddr_storage* sa) srv_lst.push_back(std::make_pair(w_sum,i)); // and fetch records with same priority + // which have not been chosen yet + int srv_lst_size=0; + unsigned int used_mask=(1<p) ){ - w_sum += ((srv_entry*)ip_vec[i])->w; - srv_lst.push_back(std::make_pair(w_sum,i)); + used_mask = used_mask << 1; + if(!(used_mask & h->srv_used)){ + w_sum += ((srv_entry*)ip_vec[i])->w; + srv_lst.push_back(std::make_pair(w_sum,i)); + srv_lst_size++; + } } srv_entry* e=NULL; - if((i - index > 1) && w_sum){ + if((srv_lst_size > 1) && w_sum){ // multiple records: apply weigthed load balancing - // - // TODO: // - remember the entries which have already been used - // unsigned int r = rand() % (w_sum+1); list >::iterator srv_lst_it = srv_lst.begin(); while(srv_lst_it != srv_lst.end()){ if(srv_lst_it->first >= r){ - //TODO: add this entry to some "already tried" list belonging to the dns handle + h->srv_used |= (1<<(srv_lst_it->second)); e = (srv_entry*)ip_vec[srv_lst_it->second]; } } @@ -168,7 +181,7 @@ int dns_srv_entry::next_ip(dns_handle* h, sockaddr_storage* sa) else { // single record or all weights == 0 e = (srv_entry*)ip_vec[index]; - if(++index >= (int)ip_vec.size()){ + if( (++i >= (int)ip_vec.size()) || (i>=(int)MAX_SRV_RR)){ h->srv_n = -1; } } diff --git a/core/sip/resolver.h b/core/sip/resolver.h index 5c86eeb8..4e9c535b 100644 --- a/core/sip/resolver.h +++ b/core/sip/resolver.h @@ -115,6 +115,7 @@ private: dns_srv_entry* srv_e; int srv_n; + unsigned int srv_used; unsigned short port; dns_ip_entry* ip_e;