Browse code

sip: fns: solved some memory management issues

Raphael Coeffic authored on 19/12/2013 14:50:56
Showing 2 changed files
... ...
@@ -45,9 +45,11 @@
45 45
 #include <arpa/nameser.h> 
46 46
 
47 47
 #include <list>
48
+#include <utility>
48 49
 #include <algorithm>
49 50
 
50 51
 using std::pair;
52
+using std::make_pair;
51 53
 using std::list;
52 54
 
53 55
 #include "log.h"
... ...
@@ -588,7 +590,7 @@ int rr_to_dns_entry(dns_record* rr, dns_section_type t,
588 590
 	    // unsupported record type
589 591
 	    return 0;
590 592
 	}
591
-	h->entry_map[name] = dns_e;
593
+	h->entry_map.insert(name,dns_e);
592 594
     }
593 595
     else {
594 596
 	dns_e = it->second;
... ...
@@ -725,6 +727,46 @@ dns_base_entry* dns_naptr_entry::get_rr(dns_record* rr, u_char* begin, u_char* e
725 727
     return naptr_r;
726 728
 }
727 729
 
730
+dns_entry_map::dns_entry_map()
731
+    : map<string,dns_entry*>()
732
+{
733
+}
734
+
735
+dns_entry_map::~dns_entry_map()
736
+{
737
+    for(iterator it = begin(); it != end(); ++it) {
738
+	dec_ref(it->second);
739
+    }
740
+}
741
+
742
+std::pair<dns_entry_map::iterator, bool>
743
+dns_entry_map::insert(const dns_entry_map::value_type& x)
744
+{
745
+    return dns_entry_map_base::insert(x);
746
+}
747
+
748
+bool dns_entry_map::insert(const string& key, dns_entry* e)
749
+{
750
+    std::pair<iterator, bool> res =
751
+    	insert(make_pair<const key_type&,mapped_type>(key,e));
752
+
753
+    if(res.second) {
754
+	inc_ref(e);
755
+	return true;
756
+    }
757
+
758
+    return false;
759
+}
760
+
761
+dns_entry* dns_entry_map::fetch(const key_type& key)
762
+{
763
+    iterator it = find(key);
764
+    if(it != end())
765
+	return it->second;
766
+    return NULL;
767
+}
768
+
769
+
728 770
 _resolver::_resolver()
729 771
     : cache(DNS_CACHE_SIZE)
730 772
 {
... ...
@@ -765,18 +807,10 @@ int _resolver::query_dns(const char* name, dns_entry_map& entry_map, dns_rr_type
765 807
 	it != h.entry_map.end(); it++) {
766 808
 
767 809
 	dns_entry* e = it->second;
768
-	if(!e) continue;
769
-
770
-	if((e)->ip_vec.empty()){
771
-	    delete e;
772
-	    e = NULL;
773
-	    continue;
774
-	}
810
+	if(!e || e->ip_vec.empty()) continue;
775 811
 
776 812
 	e->init();
777
-	//inc_ref(e);
778
-
779
-	entry_map[it->first] = e;
813
+	entry_map.insert(it->first,e);
780 814
     }
781 815
 
782 816
     return 0;
... ...
@@ -826,45 +860,28 @@ int _resolver::resolve_name(const char* name,
826 860
 	return -1;
827 861
     }
828 862
 
829
-    int res = -1;
830 863
     for(dns_entry_map::iterator it = entry_map.begin();
831 864
 	it != entry_map.end(); it++) {
832 865
 
833
-	dns_entry*& e = it->second;
834
-	if(e) {
835
-
836
-	    b = cache.get_bucket(hashlittle(it->first.c_str(),
837
-					    it->first.length(),0));
838
-	    // cache the new record
839
-	    if(!b->insert(it->first,e)) {
840
-		// record already cached
841
-
842
-		// this should allow us to avoid some race conditions
843
-		// ex: two simultanous exact same DNS queries
844
-		// -> one will be cached, the other gets destroyed after use
845
-		if(it->first != name) {
846
-		    delete e;
847
-		    e = NULL;
848
-		}
849
-		continue;
850
-	    }
851
-	    
852
-	    DBG("inserted: '%s' -> %s",
853
-		it->first.c_str(),
854
-		e->to_str().c_str());
866
+	if(!it->second) continue;
867
+
868
+	b = cache.get_bucket(hashlittle(it->first.c_str(),
869
+					it->first.length(),0));
870
+	// cache the new record
871
+	if(b->insert(it->first,it->second)) {
872
+	    // cache insert successful
873
+	    DBG("new DNS cache entry: '%s' -> %s",
874
+		it->first.c_str(), it->second->to_str().c_str());
855 875
 	}
856 876
     }
857 877
 
858
-    dns_entry_map::iterator it = entry_map.find(name);
859
-    if(it != entry_map.end()) {
860
-	dns_entry* e = it->second;
861
-	if(e) {
862
-	    // now we should have a valid IP
863
-	    res = e->next_ip(h,sa);
864
-	}
878
+    e = entry_map.fetch(name);
879
+    if(e) {
880
+	// now we should have a valid IP
881
+	return e->next_ip(h,sa);
865 882
     }
866 883
 
867
-    return res;
884
+    return -1;
868 885
 }
869 886
 
870 887
 int _resolver::str2ip(const char* name,
... ...
@@ -940,6 +957,7 @@ void _resolver::run()
940 957
     }
941 958
 }
942 959
 
960
+
943 961
 /** EMACS **
944 962
  * Local variables:
945 963
  * mode: c++
... ...
@@ -37,8 +37,10 @@
37 37
 
38 38
 #include <string>
39 39
 #include <vector>
40
+#include <map>
40 41
 using std::string;
41 42
 using std::vector;
43
+using std::map;
42 44
 
43 45
 #include <netinet/in.h>
44 46
 
... ...
@@ -203,7 +205,23 @@ public:
203 205
     int next_ip(dns_handle* h, sockaddr_storage* sa) { return -1; }
204 206
 };
205 207
 
206
-typedef map<string,dns_entry*> dns_entry_map;
208
+typedef map<string,dns_entry*> dns_entry_map_base;
209
+
210
+class dns_entry_map
211
+     : public dns_entry_map_base
212
+{
213
+public:
214
+    dns_entry_map();
215
+    ~dns_entry_map();
216
+
217
+    bool insert(const key_type& key, mapped_type e);
218
+    dns_entry* fetch(const key_type& key);
219
+
220
+private:
221
+    // forbid some inherited methods
222
+    mapped_type& operator[](const key_type& k);
223
+    std::pair<iterator, bool> insert(const value_type& x);
224
+};
207 225
 
208 226
 class _resolver
209 227
     : AmThread