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
 	Various message IDs have been renamed to remove the word 'ERROR'
 	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
 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 (
         addr_ == other.addr_ &&
         ext_ == other.ext_ &&
         hwaddr_ == other.hwaddr_ &&
-        *client_id_ == *other.client_id_ &&
         t1_ == other.t1_ &&
         t2_ == other.t2_ &&
         valid_lft_ == other.valid_lft_ &&

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

@@ -338,12 +338,25 @@ public:
         bind_[1].length = &hwaddr_length_;
 
         // 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
         bind_[3].buffer_type = MYSQL_TYPE_LONG;