Browse Source

[master] Merge branch 'trac2697' (bugfix for dhcp4 and MySQL)

Conflicts:
	ChangeLog
Tomek Mrugalski 12 years ago
parent
commit
5aa5b4e403
3 changed files with 36 additions and 7 deletions
  1. 5 0
      ChangeLog
  2. 12 1
      src/lib/dhcpsrv/lease_mgr.cc
  3. 19 6
      src/lib/dhcpsrv/mysql_lease_mgr.cc

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+569.	[bug]		tomek
+	b10-dhcp4: Fix bug whereby a DHCP packet without a client ID
+	could crash the MySQL lease database backend.
+	(Trac #2697, git b5e2be95d21ed750ad7cf5e15de2058aa8bc45f4)
+
 568.	[func]          muks
 568.	[func]          muks
 	Various message IDs have been renamed to remove the word 'ERROR'
 	Various message IDs have been renamed to remove the word 'ERROR'
 	from them when they are not logged at ERROR severity level.
 	from them when they are not logged at ERROR severity level.

+ 12 - 1
src/lib/dhcpsrv/lease_mgr.cc

@@ -113,11 +113,22 @@ Lease4::toText() const {
 
 
 bool
 bool
 Lease4::operator==(const Lease4& other) const {
 Lease4::operator==(const Lease4& other) const {
+    if ( (client_id_ && !other.client_id_) ||
+         (!client_id_ && other.client_id_) ) {
+        // One lease has client-id, but the other doesn't
+        return false;
+    }
+
+    if (client_id_ && other.client_id_ &&
+        *client_id_ != *other.client_id_) {
+        // Different client-ids
+        return false;
+    }
+
     return (
     return (
         addr_ == other.addr_ &&
         addr_ == other.addr_ &&
         ext_ == other.ext_ &&
         ext_ == other.ext_ &&
         hwaddr_ == other.hwaddr_ &&
         hwaddr_ == other.hwaddr_ &&
-        *client_id_ == *other.client_id_ &&
         t1_ == other.t1_ &&
         t1_ == other.t1_ &&
         t2_ == other.t2_ &&
         t2_ == other.t2_ &&
         valid_lft_ == other.valid_lft_ &&
         valid_lft_ == other.valid_lft_ &&

+ 19 - 6
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -338,12 +338,25 @@ public:
         bind_[1].length = &hwaddr_length_;
         bind_[1].length = &hwaddr_length_;
 
 
         // client_id: varbinary(128)
         // client_id: varbinary(128)
-        client_id_ = lease_->client_id_->getClientId();
-        client_id_length_ = client_id_.size();
-        bind_[2].buffer_type = MYSQL_TYPE_BLOB;
-        bind_[2].buffer = reinterpret_cast<char*>(&client_id_[0]);
-        bind_[2].buffer_length = client_id_length_;
-        bind_[2].length = &client_id_length_;
+        if (lease_->client_id_) {
+            client_id_ = lease_->client_id_->getClientId();
+            client_id_length_ = client_id_.size();
+            bind_[2].buffer_type = MYSQL_TYPE_BLOB;
+            bind_[2].buffer = reinterpret_cast<char*>(&client_id_[0]);
+            bind_[2].buffer_length = client_id_length_;
+            bind_[2].length = &client_id_length_;
+        } else {
+            bind_[2].buffer_type = MYSQL_TYPE_NULL;
+
+            // According to http://dev.mysql.com/doc/refman/5.5/en/
+            // c-api-prepared-statement-data-structures.html, the other
+            // fields doesn't matter if type is set to MYSQL_TYPE_NULL,
+            // but let's set them to some sane values in case earlier versions
+            // didn't have that assumption.
+            static my_bool no_clientid = MLM_TRUE;
+            bind_[2].buffer = NULL;
+            bind_[2].is_null = &no_clientid;
+        }
 
 
         // valid lifetime: unsigned int
         // valid lifetime: unsigned int
         bind_[3].buffer_type = MYSQL_TYPE_LONG;
         bind_[3].buffer_type = MYSQL_TYPE_LONG;