Skip to content
GitLab
Projects
Groups
Snippets
/
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
301cadd1
Commit
301cadd1
authored
Feb 18, 2011
by
JINMEI Tatuya
Browse files
[trac61] documented the functions. not the main subject this ticket,
but it was missing so far and should be provided.
parent
fa007383
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/lib/dns/dnssectime.cc
View file @
301cadd1
...
...
@@ -38,12 +38,12 @@ isLeap(const int y) {
return
((((
y
)
%
4
)
==
0
&&
((
y
)
%
100
)
!=
0
)
||
((
y
)
%
400
)
==
0
);
}
int
unsigned
int
yearSecs
(
const
int
year
)
{
return
((
isLeap
(
year
)
?
366
:
365
)
*
86400
);
}
int
unsigned
int
monthSecs
(
const
int
month
,
const
int
year
)
{
return
((
days
[
month
]
+
((
month
==
1
&&
isLeap
(
year
))
?
1
:
0
))
*
86400
);
}
...
...
@@ -53,15 +53,15 @@ namespace isc {
namespace
dns
{
string
timeToText64
(
uint64_t
t
)
{
timeToText64
(
uint64_t
value
)
{
struct
tm
tm
;
int
secs
;
unsigned
int
secs
;
// We cannot rely on gmtime() because time_t may not be of 64 bit
// integer. The following conversion logic is borrowed from BIND 9.
tm
.
tm_year
=
70
;
while
((
secs
=
yearSecs
(
tm
.
tm_year
+
1900
))
<=
t
)
{
t
-=
secs
;
while
((
secs
=
yearSecs
(
tm
.
tm_year
+
1900
))
<=
value
)
{
value
-=
secs
;
++
tm
.
tm_year
;
if
(
tm
.
tm_year
+
1900
>
9999
)
{
isc_throw
(
InvalidTime
,
...
...
@@ -70,26 +70,26 @@ timeToText64(uint64_t t) {
}
}
tm
.
tm_mon
=
0
;
while
((
secs
=
monthSecs
(
tm
.
tm_mon
,
tm
.
tm_year
+
1900
))
<=
t
)
{
t
-=
secs
;
while
((
secs
=
monthSecs
(
tm
.
tm_mon
,
tm
.
tm_year
+
1900
))
<=
value
)
{
value
-=
secs
;
tm
.
tm_mon
++
;
}
tm
.
tm_mday
=
1
;
while
(
86400
<=
t
)
{
t
-=
86400
;
while
(
86400
<=
value
)
{
value
-=
86400
;
++
tm
.
tm_mday
;
}
tm
.
tm_hour
=
0
;
while
(
3600
<=
t
)
{
t
-=
3600
;
while
(
3600
<=
value
)
{
value
-=
3600
;
++
tm
.
tm_hour
;
}
tm
.
tm_min
=
0
;
while
(
60
<=
t
)
{
t
-=
60
;
while
(
60
<=
value
)
{
value
-=
60
;
++
tm
.
tm_min
;
}
tm
.
tm_sec
=
t
;
// now t < 60, so this substitution is safe.
tm
.
tm_sec
=
value
;
// now t < 60, so this substitution is safe.
ostringstream
oss
;
oss
<<
setfill
(
'0'
)
...
...
@@ -130,14 +130,14 @@ gettimeofdayWrapper() {
}
string
timeToText32
(
const
uint32_t
time
val
)
{
timeToText32
(
const
uint32_t
val
ue
)
{
// We first adjust the time to the closest epoch based on the current time.
// Note that the following variables must be signed in order to handle
// time until year 2038 correctly.
const
int64_t
start
=
gettimeofdayWrapper
()
-
0x7fffffff
;
int64_t
base
=
0
;
int64_t
t
;
while
((
t
=
(
base
+
time
val
))
<
start
)
{
while
((
t
=
(
base
+
val
ue
))
<
start
)
{
base
+=
0x100000000LL
;
}
...
...
@@ -203,6 +203,8 @@ timeFromText64(const string& time_txt) {
uint32_t
timeFromText32
(
const
string
&
time_txt
)
{
// The implicit conversion from uint64_t to uint32_t should just work here,
// because we only need to drop higher 32 bits.
return
(
timeFromText64
(
time_txt
));
}
}
...
...
src/lib/dns/dnssectime.h
View file @
301cadd1
...
...
@@ -39,17 +39,102 @@ public:
isc
::
Exception
(
file
,
line
,
what
)
{}
};
uint32_t
timeFromText32
(
const
std
::
string
&
time_txt
);
///
/// \name DNSSEC time conversion functions.
///
/// These functions convert between times represented in seconds (in integer)
/// since epoch and those in the textual form used in the RRSIG records.
/// For integers we provide both 32-bit and 64-bit versions.
/// The RRSIG expiration and inception fields are both 32-bit unsigned
/// integers, so 32-bit versions would be more useful for protocol operations.
/// However, with 32-bit integers we need to take into account wrap-around
/// points and compare values using the serial number arithmetic as specified
/// in RFC4034, which would be more error prone. We therefore provide 64-bit
/// versions, too.
///
/// The timezone is always UTC for these functions.
//@{
/// Convert textual DNSSEC time to integer, 64-bit version.
///
/// The textual form must only consist of digits and be in the form of
/// YYYYMMDDHHmmSS, where:
/// - YYYY must be between 1970 and 9999
/// - MM must be between 01 and 12
/// - DD must be between 01 and 31 and must be a valid day for the month
/// represented in 'MM'. For example, if MM is 04, DD cannot be 31.
/// DD can be 29 when MM is 02 only when YYYY is a leap year.
/// - HH must be between 00 and 23
/// - mm must be between 00 and 59
/// - SS must be between 00 and 60
///
/// For all fields the range includes the begin and end values. Note that
/// 60 is allowed for 'SS', intending a leap second, although in real operation
/// it's unlikely to be specified.
///
/// If the given text is valid, this function converts it to an unsigned
/// 64-bit number of seconds since epoch (1 January 1970 00:00:00) and returns
/// the converted value. 64 bits are sufficient to represent all possible
/// values for the valid format uniquely, so there is no overflow.
///
/// \note RFC4034 also defines the textual form of an unsigned decimal integer
/// for the corresponding time in seconds. This function doesn't support
/// this form, and if given it throws an exception of class \c InvalidTime.
///
/// \exception InvalidTime The given textual representation is invalid.
///
/// \param time_txt Textual time in the form of YYYYMMDDHHmmSS
/// \return Seconds since epoch corresponding to \c time_txt
uint64_t
timeFromText64
(
const
std
::
string
&
time_txt
);
/// Convert textual DNSSEC time to integer, 32-bit version.
///
/// This version is the same as \c timeFromText64() except that the return
/// value is wrapped around to an unsigned 32-bit integer, simply dropping
/// the upper 32 bits.
uint32_t
timeFromText32
(
const
std
::
string
&
time_txt
);
/// Convert integral DNSSEC time to textual form, 64-bit version.
///
/// This function takes an integer that would be seconds since epoch and
/// converts it in the form of YYYYMMDDHHmmSS. For example, if \c value is
/// 0, it returns "19700101000000". If the value corresponds to a point
/// of time on and after year 10,000, which cannot be represented in the
/// YYYY... form, an exception of class \c InvalidTime will be thrown.
///
/// \exception InvalidTime The given time specifies on or after year 10,000.
/// \exception Other A standard exception, if resource allocation for the
/// returned text fails.
///
/// \param value Seconds since epoch to be converted.
/// \return Textual representation of \c value in the form of YYYYMMDDHHmmSS.
std
::
string
timeToText
32
(
const
uint
32
_t
time
val
);
timeToText
64
(
uint
64
_t
val
ue
);
/// Convert integral DNSSEC time to textual form, 32-bit version.
///
/// This version is the same as \c timeToText64(), but the time value
/// is expected to be the lower 32 bits of the full 64-bit value.
/// These two will be different on and after a certain point of time
/// in year 2106, so this function internally resolves the ambiguity
/// using the current system time at the time of function call;
/// it first identifies the range of [N*2^32 - 2^31, N*2^32 + 2^31)
/// that contains the current time, and interprets \c value in the context
/// of that range. It then applies the same process as \c timeToText64().
///
/// There is one important exception in this processing, however.
/// Until 19 Jan 2038 03:14:08 (2^31 seconds since epoch), this range
/// would contain time before epoch. In order to ensure the returned
/// value is also a valid input to \c timeFromText, this function uses
/// a special range [0, 2^32) until that time. As a result, all upper
/// half of the 32-bit values are treated as a future time. For example,
/// 2^32-1 (the highest value in 32-bit unsigned integers) will be converted
/// to "21060207062815", instead of "19691231235959".
std
::
string
timeToText64
(
uint64_t
t
);
timeToText32
(
uint32_t
value
);
//@}
}
}
...
...
src/lib/dns/tests/dnssectime_unittest.cc
View file @
301cadd1
...
...
@@ -54,7 +54,8 @@ TEST_F(DNSSECTimeTest, fromText) {
EXPECT_THROW
(
timeFromText32
(
"2011 101120000"
),
InvalidTime
);
EXPECT_THROW
(
timeFromText32
(
"201101011200-0"
),
InvalidTime
);
// Short length
// Short length (or "decimal integer" version of representation;
// it's valid per RFC4034, but is not supported in this implementation)
EXPECT_THROW
(
timeFromText32
(
"20100223"
),
InvalidTime
);
// Leap year checks
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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