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
0d98fbf5
Commit
0d98fbf5
authored
Jul 10, 2013
by
Tomek Mrugalski
🛰
Browse files
[2995] Changes after review.
parent
682cac0d
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/dhcp6_hooks.dox
View file @
0d98fbf5
...
...
@@ -19,7 +19,7 @@
BIND10 features an API (the "Hooks" API) that allows user-written code to
be integrated into BIND 10 and called at specific points in its processing.
An overview of the API and a tutorial for writing generalised hook code can
API can be found in @ref hookDevelopersGuide.
API can be found in @ref hook
s
DevelopersGuide
and @ref hooksComponentDeveloperGuide
.
This manual is more specialised and is aimed at developers of hook
code for the DHCPv6 server. It describes each hook point, the callouts
...
...
@@ -51,7 +51,7 @@ packet processing. Hook points that are not specific to packet processing
@subsection dhcpv6HooksPkt6Receive pkt6_receive
- @b Arguments:
- name: @b
pkt
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- name: @b
query
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- @b Description: this callout is executed when an incoming DHCPv6
packet is received and its content is parsed. The sole argument -
...
...
@@ -71,7 +71,7 @@ packet processing. Hook points that are not specific to packet processing
@subsection dhcpv6HooksSubnet6Select subnet6_select
- @b Arguments:
- name: @b
pkt
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- name: @b
query
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- name: @b subnet6, type: isc::dhcp::Subnet6Ptr, direction: <b>in/out</b>
- name: @b subnet6collection, type: const isc::dhcp::Subnet6Collection&, direction: <b>in</b>
...
...
@@ -113,7 +113,7 @@ packet processing. Hook points that are not specific to packet processing
@subsection dhcpv6HooksPkt6Send pkt6_send
- @b Arguments:
- name: @b
pkt
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- name: @b
response
6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
- @b Description: this callout is executed when server's response
is about to be send back to the client. The sole argument - pkt6 -
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
0d98fbf5
...
...
@@ -210,8 +210,13 @@ bool Dhcpv6Srv::run() {
if
(
HooksManager
::
getHooksManager
().
calloutsPresent
(
hook_index_pkt6_receive_
))
{
CalloutHandlePtr
callout_handle
=
getCalloutHandle
(
query
);
// This is the first callout, so no need to clear any arguments
callout_handle
->
setArgument
(
"pkt6"
,
query
);
// Delete previously set arguments
callout_handle
->
deleteAllArguments
();
// Pass incoming packet as argument
callout_handle
->
setArgument
(
"query6"
,
query
);
// Call callouts
HooksManager
::
getHooksManager
().
callCallouts
(
hook_index_pkt6_receive_
,
*
callout_handle
);
...
...
@@ -223,7 +228,7 @@ bool Dhcpv6Srv::run() {
continue
;
}
callout_handle
->
getArgument
(
"
pkt
6"
,
query
);
callout_handle
->
getArgument
(
"
query
6"
,
query
);
}
try
{
...
...
@@ -298,7 +303,7 @@ bool Dhcpv6Srv::run() {
// Execute all callouts registered for packet6_send
if
(
HooksManager
::
getHooksManager
().
calloutsPresent
(
hook_index_pkt6_send_
))
{
boost
::
shared_ptr
<
CalloutHandle
>
callout_handle
=
getCalloutHandle
(
query
);
CalloutHandle
Ptr
callout_handle
=
getCalloutHandle
(
query
);
// Delete all previous arguments
callout_handle
->
deleteAllArguments
();
...
...
@@ -307,7 +312,7 @@ bool Dhcpv6Srv::run() {
callout_handle
->
setSkip
(
false
);
// Set our response
callout_handle
->
setArgument
(
"
pkt
6"
,
rsp
);
callout_handle
->
setArgument
(
"
response
6"
,
rsp
);
// Call all installed callouts
HooksManager
::
getHooksManager
().
callCallouts
(
hook_index_pkt6_send_
,
...
...
@@ -654,12 +659,17 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
// Let's execute all callouts registered for packet_received
if
(
HooksManager
::
getHooksManager
().
calloutsPresent
(
hook_index_subnet6_select_
))
{
boost
::
shared_ptr
<
CalloutHandle
>
callout_handle
=
getCalloutHandle
(
question
);
CalloutHandlePtr
callout_handle
=
getCalloutHandle
(
question
);
// We're reusing callout_handle from previous calls
callout_handle
->
deleteAllArguments
();
//
This is the first callout, so no need to clear any
arguments
callout_handle
->
setArgument
(
"
pkt
6"
,
question
);
//
Set new
arguments
callout_handle
->
setArgument
(
"
query
6"
,
question
);
callout_handle
->
setArgument
(
"subnet6"
,
subnet
);
callout_handle
->
setArgument
(
"subnet6collection"
,
CfgMgr
::
instance
().
getSubnets6
());
// Call user (and server-side) callouts
HooksManager
::
getHooksManager
().
callCallouts
(
hook_index_subnet6_select_
,
*
callout_handle
);
...
...
@@ -1223,8 +1233,16 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
}
isc
::
hooks
::
CalloutHandlePtr
Dhcpv6Srv
::
getCalloutHandle
(
const
Pkt6Ptr
&
pkt
)
{
CalloutHandlePtr
callout_handle
;
// This method returns a CalloutHandle for a given packet. It is guaranteed
// to return the same callout_handle (so user library contexts are
// preserved). This method works well if the server processes one packet
// at a time. Once the server architecture is extended to cover parallel
// packets processing (e.g. delayed-ack, some form of buffering etc.), this
// method has to be extended (e.g. store callouts in a map and use pkt as
// a key). Additional code would be required to release the callout handle
// once the server finished processing.
CalloutHandlePtr
callout_handle
;
static
Pkt6Ptr
old_pointer
;
if
(
!
callout_handle
||
...
...
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
0d98fbf5
...
...
@@ -1831,11 +1831,17 @@ TEST_F(Dhcpv6SrvTest, Hooks) {
NakedDhcpv6Srv
srv
(
0
);
// check if appropriate hooks are registered
int
hook_index_pkt6_received
=
-
1
;
int
hook_index_select_subnet
=
-
1
;
int
hook_index_pkt6_send
=
-
1
;
// check if appropriate indexes are set
int
hook_index_pkt6_received
=
ServerHooks
::
getServerHooks
().
getIndex
(
"pkt6_receive"
);
int
hook_index_select_subnet
=
ServerHooks
::
getServerHooks
().
getIndex
(
"subnet6_select"
);
int
hook_index_pkt6_send
=
ServerHooks
::
getServerHooks
().
getIndex
(
"pkt6_send"
);
EXPECT_NO_THROW
(
hook_index_pkt6_received
=
ServerHooks
::
getServerHooks
()
.
getIndex
(
"pkt6_receive"
));
EXPECT_NO_THROW
(
hook_index_select_subnet
=
ServerHooks
::
getServerHooks
()
.
getIndex
(
"subnet6_select"
));
EXPECT_NO_THROW
(
hook_index_pkt6_send
=
ServerHooks
::
getServerHooks
()
.
getIndex
(
"pkt6_send"
));
EXPECT_TRUE
(
hook_index_pkt6_received
>
0
);
EXPECT_TRUE
(
hook_index_select_subnet
>
0
);
...
...
@@ -1900,6 +1906,8 @@ Pkt6* captureSimpleSolicit() {
class
HooksDhcpv6SrvTest
:
public
Dhcpv6SrvTest
{
public:
/// @brief creates Dhcpv6Srv and prepares buffers for callouts
HooksDhcpv6SrvTest
()
{
// Allocate new DHCPv6 Server
...
...
@@ -1909,10 +1917,19 @@ public:
resetCalloutBuffers
();
}
/// @brief destructor (deletes Dhcpv6Srv)
~
HooksDhcpv6SrvTest
()
{
delete
srv_
;
}
/// @brief creates an option with specified option code
///
/// This method is static, because it is used from callouts
/// that do not have a pointer to HooksDhcpv6SSrvTest object
///
/// @param option_code code of option to be created
///
/// @return pointer to create option object
static
OptionPtr
createOption
(
uint16_t
option_code
)
{
char
payload
[]
=
{
...
...
@@ -1923,23 +1940,27 @@ public:
return
OptionPtr
(
new
Option
(
Option
::
V6
,
option_code
,
tmp
));
}
/// callback that stores received callout name and pkt6 value
/// test callback that stores received callout name and pkt6 value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_receive_callout
(
CalloutHandle
&
callout_handle
)
{
callback_name_
=
string
(
"pkt6_receive"
);
callout_handle
.
getArgument
(
"
pkt
6"
,
callback_pkt6_
);
callout_handle
.
getArgument
(
"
query
6"
,
callback_pkt6_
);
callback_argument_names_
=
callout_handle
.
getArgumentNames
();
return
(
0
);
}
// callback that changes client-id value
/// test callback that changes client-id value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_receive_change_clientid
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
query
6"
,
pkt
);
// get rid of the old client-id
pkt
->
delOption
(
D6O_CLIENTID
);
...
...
@@ -1951,12 +1972,14 @@ public:
return
pkt6_receive_callout
(
callout_handle
);
}
// callback that deletes client-id
/// test callback that deletes client-id
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_receive_delete_clientid
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
query
6"
,
pkt
);
// get rid of the old client-id
pkt
->
delOption
(
D6O_CLIENTID
);
...
...
@@ -1965,12 +1988,14 @@ public:
return
pkt6_receive_callout
(
callout_handle
);
}
// callback that sets skip flag
/// test callback that sets skip flag
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_receive_skip
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
query
6"
,
pkt
);
callout_handle
.
setSkip
(
true
);
...
...
@@ -1978,23 +2003,27 @@ public:
return
pkt6_receive_callout
(
callout_handle
);
}
// Callback that stores received callout name and pkt6 value
/// Test callback that stores received callout name and pkt6 value
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_send_callout
(
CalloutHandle
&
callout_handle
)
{
callback_name_
=
string
(
"pkt6_send"
);
callout_handle
.
getArgument
(
"
pkt
6"
,
callback_pkt6_
);
callout_handle
.
getArgument
(
"
response
6"
,
callback_pkt6_
);
callback_argument_names_
=
callout_handle
.
getArgumentNames
();
return
(
0
);
}
// Callback that changes server-id
// Test callback that changes server-id
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_send_change_serverid
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
response
6"
,
pkt
);
// get rid of the old server-id
pkt
->
delOption
(
D6O_SERVERID
);
...
...
@@ -2006,12 +2035,14 @@ public:
return
pkt6_send_callout
(
callout_handle
);
}
// callback that deletes server-id
/// test callback that deletes server-id
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_send_delete_serverid
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
response
6"
,
pkt
);
// get rid of the old client-id
pkt
->
delOption
(
D6O_SERVERID
);
...
...
@@ -2020,12 +2051,14 @@ public:
return
pkt6_send_callout
(
callout_handle
);
}
// Callback that sets skip blag
/// Test callback that sets skip flag
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
pkt6_send_skip
(
CalloutHandle
&
callout_handle
)
{
Pkt6Ptr
pkt
;
callout_handle
.
getArgument
(
"
pkt
6"
,
pkt
);
callout_handle
.
getArgument
(
"
response
6"
,
pkt
);
callout_handle
.
setSkip
(
true
);
...
...
@@ -2033,12 +2066,14 @@ public:
return
pkt6_send_callout
(
callout_handle
);
}
// Callback that stores received callout name and subnet6 values
/// Test callback that stores received callout name and subnet6 values
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
subnet6_select_callout
(
CalloutHandle
&
callout_handle
)
{
callback_name_
=
string
(
"subnet6_select"
);
callout_handle
.
getArgument
(
"
pkt
6"
,
callback_pkt6_
);
callout_handle
.
getArgument
(
"
query
6"
,
callback_pkt6_
);
callout_handle
.
getArgument
(
"subnet6"
,
callback_subnet6_
);
callout_handle
.
getArgument
(
"subnet6collection"
,
callback_subnet6collection_
);
...
...
@@ -2046,7 +2081,9 @@ public:
return
(
0
);
}
// Callback that picks the other subnet if possible.
/// Test callback that picks the other subnet if possible.
/// @param callout_handle handle passed by the hooks framework
/// @return always 0
static
int
subnet6_select_different_subnet_callout
(
CalloutHandle
&
callout_handle
)
{
...
...
@@ -2067,6 +2104,7 @@ public:
return
(
0
);
}
/// resets buffers used to store data received by callouts
void
resetCalloutBuffers
()
{
callback_name_
=
string
(
""
);
callback_pkt6_
.
reset
();
...
...
@@ -2075,28 +2113,33 @@ public:
callback_argument_names_
.
clear
();
}
/// pointer to Dhcpv6Srv that is used in tests
NakedDhcpv6Srv
*
srv_
;
// Used in testing pkt6_receive_callout
static
string
callback_name_
;
///< string name of the received callout
// The following fields are used in testing pkt6_receive_callout
/// String name of the received callout
static
string
callback_name_
;
static
Pkt6Ptr
callback_pkt6_
;
///< Pkt6 structure returned in the callout
/// Pkt6 structure returned in the callout
static
Pkt6Ptr
callback_pkt6_
;
/// Pointer to a subnet received by callout
static
Subnet6Ptr
callback_subnet6_
;
/// A list of all available subnets (received by callout)
static
Subnet6Collection
callback_subnet6collection_
;
/// A list of all received arguments
static
vector
<
string
>
callback_argument_names_
;
};
// The following fields are used in testing pkt6_receive_callout.
// See fields description in the class for details
string
HooksDhcpv6SrvTest
::
callback_name_
;
Pkt6Ptr
HooksDhcpv6SrvTest
::
callback_pkt6_
;
Subnet6Ptr
HooksDhcpv6SrvTest
::
callback_subnet6_
;
Subnet6Collection
HooksDhcpv6SrvTest
::
callback_subnet6collection_
;
vector
<
string
>
HooksDhcpv6SrvTest
::
callback_argument_names_
;
...
...
@@ -2131,7 +2174,7 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_receive) {
// Check that all expected parameters are there
vector
<
string
>
expected_argument_names
;
expected_argument_names
.
push_back
(
string
(
"
pkt
6"
));
expected_argument_names
.
push_back
(
string
(
"
query
6"
));
EXPECT_TRUE
(
expected_argument_names
==
callback_argument_names_
);
}
...
...
@@ -2253,7 +2296,7 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_send) {
// Check that all expected parameters are there
vector
<
string
>
expected_argument_names
;
expected_argument_names
.
push_back
(
string
(
"
pkt
6"
));
expected_argument_names
.
push_back
(
string
(
"
response
6"
));
EXPECT_TRUE
(
expected_argument_names
==
callback_argument_names_
);
}
...
...
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