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
c4fb6001
Commit
c4fb6001
authored
Jun 22, 2017
by
Marcin Siodelski
Browse files
[5317] Only a single control command connection is now allowed.
parent
2688a2a8
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
View file @
c4fb6001
...
...
@@ -1066,4 +1066,50 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configReloadValid) {
::
remove
(
"test8.json"
);
}
// Verify that server returns an error if more than one connection is established.
TEST_F
(
CtrlChannelDhcpv4SrvTest
,
concurrentConnections
)
{
createUnixChannelServer
();
boost
::
scoped_ptr
<
UnixControlClient
>
client1
(
new
UnixControlClient
());
ASSERT_TRUE
(
client1
);
boost
::
scoped_ptr
<
UnixControlClient
>
client2
(
new
UnixControlClient
());
ASSERT_TRUE
(
client1
);
// Client 1 connects.
ASSERT_TRUE
(
client1
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// Client 2 connects.
ASSERT_TRUE
(
client2
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// Send the command while another client is connected.
ASSERT_TRUE
(
client2
->
sendCommand
(
"{
\"
command
\"
:
\"
list-commands
\"
}"
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// The server should not allow for concurrent connections and should send
// out an error message.
std
::
string
response
;
ASSERT_TRUE
(
client2
->
getResponse
(
response
));
EXPECT_EQ
(
"{
\"
result
\"
: 1,
\"
text
\"
:
\"
exceeded maximum number of concurrent"
" connections
\"
}"
,
response
);
// Now disconnect the first server and retry.
client1
->
disconnectFromServer
();
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
ASSERT_TRUE
(
client2
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
ASSERT_TRUE
(
client2
->
sendCommand
(
"{
\"
command
\"
:
\"
list-commands
\"
}"
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// The server should now respond ok.
ASSERT_TRUE
(
client2
->
getResponse
(
response
));
EXPECT_TRUE
(
response
.
find
(
"
\"
result
\"
: 0"
)
!=
std
::
string
::
npos
);
client2
->
disconnectFromServer
();
}
}
// End of anonymous namespace
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
View file @
c4fb6001
...
...
@@ -1088,4 +1088,51 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configReloadValid) {
::
remove
(
"test8.json"
);
}
// Verify that server returns an error if more than one connection is established.
TEST_F
(
CtrlChannelDhcpv6SrvTest
,
concurrentConnections
)
{
createUnixChannelServer
();
boost
::
scoped_ptr
<
UnixControlClient
>
client1
(
new
UnixControlClient
());
ASSERT_TRUE
(
client1
);
boost
::
scoped_ptr
<
UnixControlClient
>
client2
(
new
UnixControlClient
());
ASSERT_TRUE
(
client1
);
// Client 1 connects.
ASSERT_TRUE
(
client1
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// Client 2 connects.
ASSERT_TRUE
(
client2
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// Send the command while another client is connected.
ASSERT_TRUE
(
client2
->
sendCommand
(
"{
\"
command
\"
:
\"
list-commands
\"
}"
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// The server should not allow for concurrent connections and should send
// out an error message.
std
::
string
response
;
ASSERT_TRUE
(
client2
->
getResponse
(
response
));
EXPECT_EQ
(
"{
\"
result
\"
: 1,
\"
text
\"
:
\"
exceeded maximum number of concurrent"
" connections
\"
}"
,
response
);
// Now disconnect the first server and retry.
client1
->
disconnectFromServer
();
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
ASSERT_TRUE
(
client2
->
connectToServer
(
socket_path_
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
ASSERT_TRUE
(
client2
->
sendCommand
(
"{
\"
command
\"
:
\"
list-commands
\"
}"
));
ASSERT_NO_THROW
(
getIOService
()
->
poll
());
// The server should now respond ok.
ASSERT_TRUE
(
client2
->
getResponse
(
response
));
EXPECT_TRUE
(
response
.
find
(
"
\"
result
\"
: 0"
)
!=
std
::
string
::
npos
);
client2
->
disconnectFromServer
();
}
}
// End of anonymous namespace
src/lib/config/command_mgr.cc
View file @
c4fb6001
...
...
@@ -97,6 +97,10 @@ public:
connections_
.
clear
();
}
size_t
getConnectionsNum
()
const
{
return
(
connections_
.
size
());
}
private:
std
::
set
<
ConnectionPtr
>
connections_
;
...
...
@@ -109,7 +113,14 @@ Connection::receiveHandler(const boost::system::error_code& ec,
size_t
bytes_transferred
)
{
if
(
ec
)
{
if
(
ec
.
value
()
!=
boost
::
asio
::
error
::
operation_aborted
)
{
if
(
ec
.
value
()
==
boost
::
asio
::
error
::
eof
)
{
// Foreign host has closed the connection. We should remove it from the
// connection pool.
LOG_INFO
(
command_logger
,
COMMAND_SOCKET_CLOSED_BY_FOREIGN_HOST
)
.
arg
(
socket_
->
getNative
());
connection_pool_
.
stop
(
shared_from_this
());
}
else
if
(
ec
.
value
()
!=
boost
::
asio
::
error
::
operation_aborted
)
{
LOG_ERROR
(
command_logger
,
COMMAND_SOCKET_READ_FAIL
)
.
arg
(
ec
.
value
()).
arg
(
socket_
->
getNative
());
}
...
...
@@ -137,8 +148,13 @@ Connection::receiveHandler(const boost::system::error_code& ec,
std
::
string
sbuf
(
&
buf_
[
0
],
bytes_transferred
);
cmd
=
Element
::
fromJSON
(
sbuf
,
true
);
// If successful, then process it as a command.
rsp
=
CommandMgr
::
instance
().
processCommand
(
cmd
);
if
(
connection_pool_
.
getConnectionsNum
()
>
1
)
{
rsp
=
createAnswer
(
CONTROL_RESULT_ERROR
,
"exceeded maximum number of concurrent"
" connections"
);
}
else
{
// If successful, then process it as a command.
rsp
=
CommandMgr
::
instance
().
processCommand
(
cmd
);
}
}
catch
(
const
Exception
&
ex
)
{
LOG_WARN
(
command_logger
,
COMMAND_PROCESS_ERROR1
).
arg
(
ex
.
what
());
...
...
src/lib/config/config_messages.mes
View file @
c4fb6001
...
...
@@ -55,6 +55,10 @@ This error indicates that the server detected incoming connection and executed
accept system call on said socket, but this call returned an error. Additional
information may be provided by the system as second parameter.
% COMMAND_SOCKET_CLOSED_BY_FOREIGN_HOST Closed command socket %1 by foreign host
This is an information message indicating that the command connection has been
closed by a command control client.
% COMMAND_SOCKET_CONNECTION_CLOSED Closed socket %1 for existing command connection
This is an informational message that the socket created for handling
client's connection is closed. This usually means that the client disconnected,
...
...
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