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
Adam Osuchowski
Kea
Commits
3690baaf
Commit
3690baaf
authored
Sep 21, 2012
by
Tomek Mrugalski
🛰
Browse files
[2238] Pool, Subnet and Triplet moved to separate files.
parent
704ca46a
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/Makefile.am
View file @
3690baaf
...
...
@@ -30,6 +30,9 @@ libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h
libb10_dhcp___la_SOURCES
+=
pkt4.cc pkt4.h
libb10_dhcpsrv_la_SOURCES
=
cfgmgr.cc cfgmgr.h
libb10_dhcpsrv_la_SOURCES
+=
pool.cc pool.h
libb10_dhcpsrv_la_SOURCES
+=
subnet.cc subnet.h
libb10_dhcpsrv_la_SOURCES
+=
triplet.h
libb10_dhcpsrv_la_SOURCES
+=
addr_utilities.cc addr_utilities.h
libb10_dhcpsrv_la_CXXFLAGS
=
$(AM_CXXFLAGS)
libb10_dhcpsrv_la_CPPFLAGS
=
$(AM_CPPFLAGS)
$(LOG4CPLUS_INCLUDES)
...
...
src/lib/dhcp/cfgmgr.cc
View file @
3690baaf
...
...
@@ -12,7 +12,6 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
<dhcp/addr_utilities.h>
#include
<asiolink/io_address.h>
#include
<dhcp/cfgmgr.h>
...
...
@@ -22,132 +21,7 @@ using namespace isc::util;
namespace
isc
{
namespace
dhcp
{
Pool
::
Pool
(
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
id_
(
getNextID
()),
first_
(
first
),
last_
(
last
)
{
}
bool
Pool
::
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
return
(
first_
.
smallerEqual
(
addr
)
&&
addr
.
smallerEqual
(
last_
));
}
Pool6
::
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
Pool
(
first
,
last
),
type_
(
type
),
prefix_len_
(
0
)
{
// check if specified address boundaries are sane
if
(
first
.
getFamily
()
!=
AF_INET6
||
last
.
getFamily
()
!=
AF_INET6
)
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
if
(
last
<
first
)
{
isc_throw
(
BadValue
,
"Upper boundary is smaller than lower boundary."
);
// This check is a bit strict. If we decide that it is too strict,
// we need to comment it and uncomment lines below.
// On one hand, letting the user specify 2001::f - 2001::1 is nice, but
// on the other hand, 2001::1 may be a typo and the user really meant
// 2001::1:0 (or 1 followed by some hex digit), so a at least a warning
// would be useful.
// first_ = last;
// last_ = first;
}
// TYPE_PD is not supported by this constructor. first-last style
// parameters are for IA and TA only. There is another dedicated
// constructor for that (it uses prefix/length)
if
((
type
!=
TYPE_IA
)
&&
(
type
!=
TYPE_TA
))
{
isc_throw
(
BadValue
,
"Invalid Pool6 type specified"
);
}
}
Pool6
::
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
)
:
Pool
(
prefix
,
IOAddress
(
"::"
)),
type_
(
type
),
prefix_len_
(
prefix_len
)
{
// check if the prefix is sane
if
(
prefix
.
getFamily
()
!=
AF_INET6
)
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
// check if the prefix length is sane
if
(
prefix_len
==
0
||
prefix_len
>
128
)
{
isc_throw
(
BadValue
,
"Invalid prefix length"
);
}
/// @todo: We should probably implement checks against weird addresses
/// here, like ::, starting with fe80, starting with ff etc. .
// Let's now calculate the last address in defined pool
last_
=
lastAddrInPrefix
(
prefix
,
prefix_len
);
}
Subnet
::
Subnet
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
len
,
const
Triplet
<
uint32_t
>&
t1
,
const
Triplet
<
uint32_t
>&
t2
,
const
Triplet
<
uint32_t
>&
valid_lifetime
)
:
id_
(
getNextID
()),
prefix_
(
prefix
),
prefix_len_
(
len
),
t1_
(
t1
),
t2_
(
t2
),
valid_
(
valid_lifetime
)
{
if
(
(
prefix
.
getFamily
()
==
AF_INET6
&&
len
>
128
)
||
(
prefix
.
getFamily
()
==
AF_INET
&&
len
>
32
)
)
{
isc_throw
(
BadValue
,
"Invalid prefix length specified for subnet: "
<<
len
);
}
}
bool
Subnet
::
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
IOAddress
first
=
firstAddrInPrefix
(
prefix_
,
prefix_len_
);
IOAddress
last
=
lastAddrInPrefix
(
prefix_
,
prefix_len_
);
return
((
first
<=
addr
)
&&
(
addr
<=
last
));
}
Subnet6
::
Subnet6
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
length
,
const
Triplet
<
uint32_t
>&
t1
,
const
Triplet
<
uint32_t
>&
t2
,
const
Triplet
<
uint32_t
>&
preferred_lifetime
,
const
Triplet
<
uint32_t
>&
valid_lifetime
)
:
Subnet
(
prefix
,
length
,
t1
,
t2
,
valid_lifetime
),
preferred_
(
preferred_lifetime
){
if
(
prefix
.
getFamily
()
!=
AF_INET6
)
{
isc_throw
(
BadValue
,
"Non IPv6 prefix "
<<
prefix
.
toText
()
<<
" specified in subnet6"
);
}
}
void
Subnet6
::
addPool6
(
const
Pool6Ptr
&
pool
)
{
IOAddress
first_addr
=
pool
->
getFirstAddress
();
IOAddress
last_addr
=
pool
->
getLastAddress
();
if
(
!
inRange
(
first_addr
)
||
!
inRange
(
last_addr
))
{
isc_throw
(
BadValue
,
"Pool6 ("
<<
first_addr
.
toText
()
<<
"-"
<<
last_addr
.
toText
()
<<
" does not belong in this ("
<<
prefix_
<<
"/"
<<
prefix_len_
<<
") subnet6"
);
}
/// @todo: Check that pools do not overlap
pools_
.
push_back
(
pool
);
}
Pool6Ptr
Subnet6
::
getPool6
(
const
isc
::
asiolink
::
IOAddress
&
hint
/* = IOAddress("::")*/
)
{
Pool6Ptr
candidate
;
for
(
Pool6Collection
::
iterator
pool
=
pools_
.
begin
();
pool
!=
pools_
.
end
();
++
pool
)
{
// if we won't find anything better, then let's just use the first pool
if
(
!
candidate
)
{
candidate
=
*
pool
;
}
// if the client provided a pool and there's a pool that hint is valid in,
// then let's use that pool
if
((
*
pool
)
->
inRange
(
hint
))
{
return
(
*
pool
);
}
}
return
(
candidate
);
}
CfgMgr
&
...
...
src/lib/dhcp/cfgmgr.h
View file @
3690baaf
...
...
@@ -23,360 +23,12 @@
#include
<asiolink/io_address.h>
#include
<util/buffer.h>
#include
<dhcp/option.h>
#include
<dhcp/pool.h>
#include
<dhcp/subnet.h>
namespace
isc
{
namespace
dhcp
{
class
Pool6
;
class
Subnet6
;
/// @brief this template specifies a parameter value
///
/// This template class is used to store configuration parameters, like lifetime or T1.
/// It defines 3 parameters: min, default, and max value. There are 2 constructors:
/// - simple (just one value that sets all parameters)
/// - extended (that sets default value and two thresholds)
/// It will be used with integer types. It provides necessary operators, so
/// it can be assigned to a plain integer or integer assigned to a Triplet.
/// See TripletTest.operator test for details on an easy Triplet usage.
template
<
class
T
>
class
Triplet
{
public:
/// @brief base type to Triple conversion
///
/// Typically: uint32_t to Triplet assignment. It is very convenient
/// to be able to simply write Triplet<uint32_t> x = 7;
Triplet
<
T
>
operator
=
(
T
other
)
{
min_
=
other
;
default_
=
other
;
max_
=
other
;
return
*
this
;
}
/// @brief triplet to base type conversion
///
/// Typically: Triplet to uint32_t assignment. It is very convenient
/// to be able to simply write uint32_t z = x; (where x is a Triplet)
operator
T
()
const
{
return
(
default_
);
}
/// @brief sets a fixed value
///
/// This constructor assigns a fixed (i.e. no range, just a single value)
/// value.
Triplet
(
T
value
)
:
min_
(
value
),
default_
(
value
),
max_
(
value
)
{
}
/// @brief sets the default value and thresholds
///
/// @throw BadValue if min <= def <= max rule is violated
Triplet
(
T
min
,
T
def
,
T
max
)
:
min_
(
min
),
default_
(
def
),
max_
(
max
)
{
if
(
(
min_
>
def
)
||
(
def
>
max_
)
)
{
isc_throw
(
BadValue
,
"Invalid triplet values."
);
}
}
/// @brief returns a minimum allowed value
T
getMin
()
const
{
return
min_
;}
/// @brief returns the default value
T
get
()
const
{
return
default_
;}
/// @brief returns value with a hint
///
/// DHCP protocol treats any values sent by a client as hints.
/// This is a method that implements that. We can assign any value
/// from configured range that client asks.
T
get
(
T
hint
)
const
{
if
(
hint
<=
min_
)
{
return
(
min_
);
}
if
(
hint
>=
max_
)
{
return
(
max_
);
}
return
(
hint
);
}
/// @brief returns a maximum allowed value
T
getMax
()
const
{
return
max_
;
}
protected:
/// @brief the minimum value
T
min_
;
/// @brief the default value
T
default_
;
/// @brief the maximum value
T
max_
;
};
/// @brief base class for Pool4 and Pool6
///
/// Stores information about pool of IPv4 or IPv6 addresses.
/// That is a basic component of a configuration.
class
Pool
{
public:
/// @brief returns Pool-id
///
/// @return pool-id value
/// Pool-id is an unique value that can be used to identify a pool.
uint32_t
getId
()
const
{
return
(
id_
);
}
/// @brief Returns the first address in a pool.
///
/// @return first address in a pool
const
isc
::
asiolink
::
IOAddress
&
getFirstAddress
()
const
{
return
(
first_
);
}
/// @brief Returns the last address in a pool.
/// @return last address in a pool
const
isc
::
asiolink
::
IOAddress
&
getLastAddress
()
const
{
return
(
last_
);
}
/// @brief Checks if a given address is in the range.
///
/// @return true, if the address is in pool
bool
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
;
protected:
/// @brief protected constructor
///
/// This constructor is protected to prevent anyone from instantiating
/// Pool class directly. Instances of Pool4 and Pool6 should be created
/// instead.
Pool
(
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
);
/// @brief returns the next unique Pool-ID
///
/// @return the next unique Pool-ID
static
uint32_t
getNextID
()
{
static
uint32_t
id
=
0
;
return
(
id
++
);
}
/// @brief pool-id
///
/// This ID is used to identify this specific pool.
uint32_t
id_
;
/// @brief The first address in a pool
isc
::
asiolink
::
IOAddress
first_
;
/// @brief The last address in a pool
isc
::
asiolink
::
IOAddress
last_
;
/// @brief Comments field
///
/// @todo: This field is currently not used.
std
::
string
comments_
;
};
/// @brief Pool information for IPv6 addresses and prefixes
///
/// It holds information about pool6, i.e. a range of IPv6 address space that
/// is configured for DHCP allocation.
class
Pool6
:
public
Pool
{
public:
/// @brief specifies Pool type
///
/// Currently there are 3 pool types defined in DHCPv6:
/// - Non-temporary addresses (conveyed in IA_NA)
/// - Temporary addresses (conveyed in IA_TA)
/// - Delegated Prefixes (conveyed in IA_PD)
/// There is a new one being worked on (IA_PA, see draft-ietf-dhc-host-gen-id), but
/// support for it is not planned for now.
typedef
enum
{
TYPE_IA
,
TYPE_TA
,
TYPE_PD
}
Pool6Type
;
/// @brief the constructor for Pool6 "min-max" style definition
///
/// @param first the first address in a pool
/// @param last the last address in a pool
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
);
/// @brief the constructor for Pool6 "prefix/len" style definition
///
/// @param prefix specifies prefix of the pool
/// @param prefix_len specifies length of the prefix of the pool
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
);
/// @brief returns pool type
///
/// @return pool type
Pool6Type
getType
()
const
{
return
(
type_
);
}
private:
/// @brief defines a pool type
Pool6Type
type_
;
/// @brief prefix length
/// used by TYPE_PD only (zeroed for other types)
uint8_t
prefix_len_
;
};
/// @brief a pointer an IPv6 Pool
typedef
boost
::
shared_ptr
<
Pool6
>
Pool6Ptr
;
/// @brief a container for IPv6 Pools
typedef
std
::
vector
<
Pool6Ptr
>
Pool6Collection
;
/// @brief a base class for Subnet4 and Subnet6
///
/// This class presents a common base for IPv4 and IPv6 subnets.
/// In a physical sense, a subnet defines a single network link with all devices
/// attached to it. In most cases all devices attached to a single link can
/// share the same parameters. Therefore Subnet holds several values that are
/// typically shared by all hosts: renew timer (T1), rebind timer (T2) and
/// leased addresses lifetime (valid-lifetime).
///
/// @todo: Implement support for options here
class
Subnet
{
public:
/// @brief checks if specified address is in range
bool
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
;
/// @brief return valid-lifetime for addresses in that prefix
Triplet
<
uint32_t
>
getValid
()
const
{
return
(
valid_
);
}
/// @brief returns T1 (renew timer), expressed in seconds
Triplet
<
uint32_t
>
getT1
()
const
{
return
(
t1_
);
}
/// @brief returns T2 (rebind timer), expressed in seconds
Triplet
<
uint32_t
>
getT2
()
const
{
return
(
t2_
);
}
protected:
/// @brief protected constructor
//
/// By making the constructor protected, we make sure that noone will
/// ever instantiate that class. Pool4 and Pool6 should be used instead.
Subnet
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
len
,
const
Triplet
<
uint32_t
>&
t1
,
const
Triplet
<
uint32_t
>&
t2
,
const
Triplet
<
uint32_t
>&
valid_lifetime
);
/// @brief returns the next unique Subnet-ID
///
/// @return the next unique Subnet-ID
static
uint32_t
getNextID
()
{
static
uint32_t
id
=
0
;
return
(
id
++
);
}
/// @brief subnet-id
///
/// Subnet-id is a unique value that can be used to find or identify
/// a Subnet4 or Subnet6.
uint32_t
id_
;
/// @brief a prefix of the subnet
isc
::
asiolink
::
IOAddress
prefix_
;
/// @brief a prefix length of the subnet
uint8_t
prefix_len_
;
/// @brief a tripet (min/default/max) holding allowed renew timer values
Triplet
<
uint32_t
>
t1_
;
/// @brief a tripet (min/default/max) holding allowed rebind timer values
Triplet
<
uint32_t
>
t2_
;
/// @brief a tripet (min/default/max) holding allowed valid lifetime values
Triplet
<
uint32_t
>
valid_
;
};
/// @brief A configuration holder for IPv6 subnet.
///
/// This class represents an IPv6 subnet.
class
Subnet6
:
public
Subnet
{
public:
/// @brief Constructor with all parameters
///
/// @param prefix Subnet6 prefix
/// @param length prefix length
/// @param t1 renewal timer (in seconds)
/// @param t2 rebind timer (in seconds)
/// @param preferred_lifetime preferred lifetime of leases (in seconds)
/// @param valid_lifetime preferred lifetime of leases (in seconds)
Subnet6
(
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
length
,
const
Triplet
<
uint32_t
>&
t1
,
const
Triplet
<
uint32_t
>&
t2
,
const
Triplet
<
uint32_t
>&
preferred_lifetime
,
const
Triplet
<
uint32_t
>&
valid_lifetime
);
/// @brief Returns preverred lifetime (in seconds)
///
/// @return a triplet with preferred lifetime
Triplet
<
uint32_t
>
getPreferred
()
const
{
return
(
preferred_
);
}
/// @brief Returns a pool that specified address belongs to
///
/// @param hint address that the returned pool should cover (optional)
/// @return Pointer to found pool6 (or NULL)
Pool6Ptr
getPool6
(
const
isc
::
asiolink
::
IOAddress
&
hint
=
isc
::
asiolink
::
IOAddress
(
"::"
));
/// @brief Adds a new pool.
/// @param pool pool to be added
void
addPool6
(
const
Pool6Ptr
&
pool
);
/// @brief returns all pools
///
/// The reference is only valid as long as the object that
/// returned it.
///
/// @return a collection of all pools
const
Pool6Collection
&
getPools
()
const
{
return
pools_
;
}
protected:
/// @brief collection of pools in that list
Pool6Collection
pools_
;
/// @brief a triplet with preferred lifetime (in seconds)
Triplet
<
uint32_t
>
preferred_
;
};
/// @brief A pointer to a Subnet6 object
typedef
boost
::
shared_ptr
<
Subnet6
>
Subnet6Ptr
;
/// @brief A collection of Subnet6 objects
typedef
std
::
vector
<
Subnet6Ptr
>
Subnet6Collection
;
/// @brief Configuration Manager
///
...
...
src/lib/dhcp/pool.cc
0 → 100644
View file @
3690baaf
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
<asiolink/io_address.h>
#include
<dhcp/addr_utilities.h>
#include
<dhcp/pool.h>
using
namespace
isc
::
asiolink
;
namespace
isc
{
namespace
dhcp
{
Pool
::
Pool
(
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
id_
(
getNextID
()),
first_
(
first
),
last_
(
last
)
{
}
bool
Pool
::
inRange
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
return
(
first_
.
smallerEqual
(
addr
)
&&
addr
.
smallerEqual
(
last_
));
}
Pool6
::
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
Pool
(
first
,
last
),
type_
(
type
),
prefix_len_
(
0
)
{
// check if specified address boundaries are sane
if
(
first
.
getFamily
()
!=
AF_INET6
||
last
.
getFamily
()
!=
AF_INET6
)
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
if
(
last
<
first
)
{
isc_throw
(
BadValue
,
"Upper boundary is smaller than lower boundary."
);
// This check is a bit strict. If we decide that it is too strict,
// we need to comment it and uncomment lines below.
// On one hand, letting the user specify 2001::f - 2001::1 is nice, but
// on the other hand, 2001::1 may be a typo and the user really meant
// 2001::1:0 (or 1 followed by some hex digit), so a at least a warning
// would be useful.
// first_ = last;
// last_ = first;
}
// TYPE_PD is not supported by this constructor. first-last style
// parameters are for IA and TA only. There is another dedicated
// constructor for that (it uses prefix/length)
if
((
type
!=
TYPE_IA
)
&&
(
type
!=
TYPE_TA
))
{
isc_throw
(
BadValue
,
"Invalid Pool6 type specified"
);
}
}
Pool6
::
Pool6
(
Pool6Type
type
,
const
isc
::
asiolink
::
IOAddress
&
prefix
,
uint8_t
prefix_len
)
:
Pool
(
prefix
,
IOAddress
(
"::"
)),
type_
(
type
),
prefix_len_
(
prefix_len
)
{
// check if the prefix is sane
if
(
prefix
.
getFamily
()
!=
AF_INET6
)
{
isc_throw
(
BadValue
,
"Invalid Pool6 address boundaries: not IPv6"
);
}
// check if the prefix length is sane
if
(
prefix_len
==
0
||
prefix_len
>
128
)
{
isc_throw
(
BadValue
,
"Invalid prefix length"
);
}
/// @todo: We should probably implement checks against weird addresses
/// here, like ::, starting with fe80, starting with ff etc. .
// Let's now calculate the last address in defined pool
last_
=
lastAddrInPrefix
(
prefix
,
prefix_len
);
}
};
// end of isc::dhcp namespace
};
// end of isc namespace
src/lib/dhcp/pool.h
0 → 100644
View file @
3690baaf
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef POOL_H
#define POOL_H
#include
<vector>
#include
<asiolink/io_address.h>
#include
<boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
/// @brief base class for Pool4 and Pool6
///