Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
3e52b2fe
Commit
3e52b2fe
authored
Oct 24, 2012
by
Stephen Morris
Browse files
[2342] Fix problems with time conversion
... traced to not initializing a "struct" properly.
parent
942be75a
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/dhcpdb_create.mysql
View file @
3e52b2fe
...
...
@@ -46,7 +46,7 @@ CREATE TABLE lease6 (
address VARCHAR(40) PRIMARY KEY NOT NULL, # IPv6 address
hwaddr VARBINARY(20), # Hardware address
duid VARBINARY(128), # DUID
lease_
time INT UNSIGNED,
# Length of the lease (seconds)
valid_life
time INT UNSIGNED, # Length of the lease (seconds)
expire TIMESTAMP, # Expiration time of the lease
subnet_id INT UNSIGNED, # Subnet identification
pref_lifetime INT UNSIGNED, # Preferred lifetime
...
...
src/lib/dhcp/mysql_lease_mgr.cc
View file @
3e52b2fe
...
...
@@ -111,23 +111,19 @@ public:
bind_
[
2
].
buffer_length
=
duid_length_
;
bind_
[
2
].
length
=
&
duid_length_
;
// The lease structure holds the client last transmission time (cltt_)
// and the valid lifetime (valid_lft_). For convenience for external
// tools, the data stored in the database is expiry time (expire) and
// lease time (lease+time). The relationship is given by:
//
// lease_time - valid_lft_
// expire = cltt_ + valid_lft_
//
MySqlLeaseMgr
::
convertToDatabaseTime
(
lease_
->
cltt_
,
lease_
->
valid_lft_
,
expire_
,
lease_time_
);
// lease_time: unsigned int
bind_
[
3
].
buffer_type
=
MYSQL_TYPE_LONG
;
bind_
[
3
].
buffer
=
reinterpret_cast
<
char
*>
(
&
lease
_time
_
);
bind_
[
3
].
buffer
=
reinterpret_cast
<
char
*>
(
&
lease
->
valid_lft
_
);
bind_
[
3
].
is_unsigned
=
true_
;
// expire: timestamp
// The lease structure holds the client last transmission time (cltt_)
// For convenience for external tools, this is converted to lease
/// expiry time (expire). The relationship is given by:
//
// expire = cltt_ + valid_lft_
MySqlLeaseMgr
::
convertToDatabaseTime
(
lease_
->
cltt_
,
lease_
->
valid_lft_
,
expire_
);
bind_
[
4
].
buffer_type
=
MYSQL_TYPE_TIMESTAMP
;
bind_
[
4
].
buffer
=
reinterpret_cast
<
char
*>
(
&
expire_
);
bind_
[
4
].
buffer_length
=
sizeof
(
expire_
);
...
...
@@ -210,7 +206,7 @@ public:
// lease_time: unsigned int
bind_
[
3
].
buffer_type
=
MYSQL_TYPE_LONG
;
bind_
[
3
].
buffer
=
reinterpret_cast
<
char
*>
(
&
lease_
time_
);
bind_
[
3
].
buffer
=
reinterpret_cast
<
char
*>
(
&
valid_life
time_
);
bind_
[
3
].
is_unsigned
=
true_
;
bind_
[
3
].
error
=
&
error_
[
3
];
...
...
@@ -269,16 +265,20 @@ public:
Lease6Ptr
result
(
new
Lease6
());
// Success - put the data in the lease object
// The address buffer is declared larger than the buffer size passed
// to the access function so that we can always append a null byte.
addr6_buffer_
[
addr6_length_
]
=
'\0'
;
std
::
string
address
=
addr6_buffer_
;
result
->
addr_
=
isc
::
asiolink
::
IOAddress
(
address
);
// Set the other data, converting time as needed.
result
->
addr_
=
isc
::
asiolink
::
IOAddress
(
address
);
result
->
hwaddr_
=
vector
<
uint8_t
>
(
&
hwaddr_buffer_
[
0
],
&
hwaddr_buffer_
[
hwaddr_length_
]);
result
->
duid_
.
reset
(
new
DUID
(
duid_buffer_
,
duid_length_
));
MySqlLeaseMgr
::
convertFromDatabaseTime
(
expire_
,
lease_
time_
,
result
->
cltt_
,
result
->
valid_lft_
)
;
MySqlLeaseMgr
::
convertFromDatabaseTime
(
expire_
,
valid_life
time_
,
result
->
cltt_
);
result
->
valid_lft_
=
valid_lifetime_
;
result
->
subnet_id_
=
subnet_id_
;
result
->
preferred_lft_
=
pref_lifetime_
;
...
...
@@ -323,7 +323,7 @@ private:
unsigned
long
hwaddr_length_
;
///< Length of hardware address
uint32_t
iaid_
;
///< Identity association ID
Lease6Ptr
lease_
;
///< Pointer to lease object
uint32_t
lease_
time_
;
///< Lease time
uint32_t
valid_life
time_
;
///< Lease time
uint8_t
lease_type_
;
///< Lease type
uint8_t
prefixlen_
;
///< Prefix length
uint32_t
pref_lifetime_
;
///< Preferred lifetime
...
...
@@ -337,15 +337,21 @@ private:
//
// Note that the MySQL TIMESTAMP data type (used for "expire") converts data
// from the current timezone to UTC for storage, and from UTC to the current
// timezone for retrieval. This means that the external interface - cltt -
// must be local time.
// timezone for retrieval.
//
// This causes no problems providing that:
// a) cltt is given in local time
// b) We let the system take care of timezone conversion when converting
// from a time read from the database into a local time.
void
MySqlLeaseMgr
::
convertToDatabaseTime
(
time_t
cltt
,
uint32_t
valid_l
ft
,
MYSQL_TIME
&
expire
,
uint32_t
&
lease_time
)
{
MySqlLeaseMgr
::
convertToDatabaseTime
(
time_t
cltt
,
uint32_t
valid_l
ifetime
,
MYSQL_TIME
&
expire
)
{
// Calculate expiry time and convert to various date/time fields.
time_t
expire_time
=
cltt
+
valid_lft
;
time_t
expire_time
=
cltt
+
valid_lifetime
;
// Convert to broken-out time
struct
tm
expire_tm
;
(
void
)
localtime_r
(
&
expire_time
,
&
expire_tm
);
...
...
@@ -358,19 +364,15 @@ MySqlLeaseMgr::convertToDatabaseTime(time_t cltt, uint32_t valid_lft,
expire
.
second
=
expire_tm
.
tm_sec
;
expire
.
second_part
=
0
;
// No fractional seconds
expire
.
neg
=
static_cast
<
my_bool
>
(
0
);
// Not negative
// Set the lease time.
lease_time
=
valid_lft
;
}
void
MySqlLeaseMgr
::
convertFromDatabaseTime
(
const
MYSQL_TIME
&
expire
,
uint32_t
lease_time
,
time_t
&
cltt
,
uint32_t
&
valid_lft
)
{
valid_lft
=
lease_time
;
uint32_t
valid_lifetime
,
time_t
&
cltt
)
{
// Copy across fields from MYSQL_TIME structure.
struct
tm
expire_tm
;
memset
(
&
expire_tm
,
0
,
sizeof
(
expire_tm
));
expire_tm
.
tm_year
=
expire
.
year
-
1900
;
expire_tm
.
tm_mon
=
expire
.
month
-
1
;
...
...
@@ -378,9 +380,10 @@ MySqlLeaseMgr::convertFromDatabaseTime(const MYSQL_TIME& expire,
expire_tm
.
tm_hour
=
expire
.
hour
;
expire_tm
.
tm_min
=
expire
.
minute
;
expire_tm
.
tm_sec
=
expire
.
second
;
expire_tm
.
tm_isdst
=
-
1
;
// Let the system work out about DST
// Convert to local time
cltt
=
mktime
(
&
expire_tm
)
-
valid_l
ft
;
cltt
=
mktime
(
&
expire_tm
)
-
valid_l
ifetime
;
}
void
...
...
@@ -474,14 +477,14 @@ MySqlLeaseMgr::prepareStatements() {
"DELETE FROM lease6 WHERE address = ?"
);
prepareStatement
(
GET_LEASE6
,
"SELECT address, hwaddr, duid, "
"
lease_
time, expire, subnet_id, pref_lifetime, "
"
valid_life
time, expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len "
"FROM lease6 WHERE address = ?"
);
prepareStatement
(
GET_VERSION
,
"SELECT version, minor FROM schema_version"
);
prepareStatement
(
INSERT_LEASE6
,
"INSERT INTO lease6(address, hwaddr, duid, "
"
lease_
time, expire, subnet_id, pref_lifetime, "
"
valid_life
time, expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
);
}
...
...
src/lib/dhcp/mysql_lease_mgr.h
View file @
3e52b2fe
...
...
@@ -262,36 +262,32 @@ public:
/// @brief Convert Lease Time to Database Times
///
/// Within the DHCP servers, times are stored as
cltt (
client last transmit
///
time)
and valid
_lft (valid
lifetime
)
. In the database, the information
///
is stored as lease_time (lease
time
)
and expire (time of expiry of the
///
lease). They are
related by the equation
s
:
/// Within the DHCP servers, times are stored as client last transmit
time
/// and valid lifetime. In the database, the information
is stored as
///
valid life
time and
"
expire
"
(time of expiry of the
lease). They are
/// related by the equation:
///
/// - lease_time = valid_lft
/// - expire = cltt + valid_lft
/// - expire = client last transmit time + valid lifetime
///
/// This method converts from the times in the lease object into times
/// able to be added to the database.
///
/// @param cltt Client last transmit time
/// @param valid_l
ft
Valid lifetime
/// @param valid_l
ifetime
Valid lifetime
/// @param expire Reference to MYSQL_TIME object where the expiry time of
/// the lease will be put.
/// @param lease_time Reference to the time_t object where the lease time
/// will be put.
static
void
convertToDatabaseTime
(
time_t
cltt
,
uint32_t
valid_l
ft
,
MYSQL_TIME
&
expire
,
uint32_t
&
lease_time
);
void
convertToDatabaseTime
(
time_t
cltt
,
uint32_t
valid_l
ifetime
,
MYSQL_TIME
&
expire
);
/// @brief Convert Database Time to Lease Times
///
/// Within the database, time is stored as
lease_time (lease time) and
///
expire (time of expiry of the lease)
. In the DHCP server, the
///
information is stored as cltt (
client last transmit time
)
and
///
valid_lft (valid lifetime). These are related
by the equation
s
:
/// Within the database, time is stored as
"expire" (time of expiry of the
///
lease) and valid lifetime
. In the DHCP server, the
information is
///
stored
client last transmit time and
valid lifetime. These are related
/// by the equation:
///
/// - valid_lft = lease_time
/// - cltt = expire - lease_time
/// - client last transmit time = expire - valid_lifetime
///
/// This method converts from the times in the database into times
/// able to be inserted into the lease object.
...
...
@@ -301,10 +297,9 @@ public:
/// @param lease_time lifetime of the lease.
/// @param cltt Reference to location where client last transmit time
/// is put.
/// @param valid_lft Reference to location where valid lifetime is put.
static
void
convertFromDatabaseTime
(
const
MYSQL_TIME
&
expire
,
uint32_t
lease_time
,
time_t
&
cltt
,
uint32_t
&
valid_l
f
t
);
void
convertFromDatabaseTime
(
const
MYSQL_TIME
&
expire
,
uint32_t
valid_l
ifetime
,
time_t
&
clt
t
);
///@}
...
...
src/lib/dhcp/tests/mysql_lease_mgr_unittest.cc
View file @
3e52b2fe
...
...
@@ -132,21 +132,16 @@ TEST_F(MySqlLeaseMgrTest, CheckTimeConversion) {
const
time_t
cltt
=
time
(
NULL
);
const
uint32_t
valid_lft
=
86400
;
// 1 day
MYSQL_TIME
expire
;
uint32_t
lease_time
;
MySqlLeaseMgr
::
convertToDatabaseTime
(
cltt
,
valid_lft
,
expire
,
lease_time
);
EXPECT_EQ
(
valid_lft
,
lease_time
);
MySqlLeaseMgr
::
convertToDatabaseTime
(
cltt
,
valid_lft
,
expire
);
EXPECT_LE
(
2012
,
expire
.
year
);
// Code was written in 2012
EXPECT_EQ
(
0
,
expire
.
second_part
);
EXPECT_EQ
(
0
,
expire
.
neg
);
// Convert back
time_t
converted_cltt
=
0
;
uint32_t
converted_valid_lft
=
0
;
MySqlLeaseMgr
::
convertFromDatabaseTime
(
expire
,
lease_time
,
converted_cltt
,
converted_valid_lft
);
MySqlLeaseMgr
::
convertFromDatabaseTime
(
expire
,
valid_lft
,
converted_cltt
);
EXPECT_EQ
(
cltt
,
converted_cltt
);
EXPECT_EQ
(
valid_lft
,
converted_valid_lft
);
}
/// @brief Check that getVersion() works
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment