Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Sebastian Schrader
Kea
Commits
f4b20fc5
Commit
f4b20fc5
authored
Feb 28, 2011
by
Stephen Morris
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[trac499] Finish TCPSocket and IOFetch and associated unit tests
parent
682436e8
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
131 additions
and
138 deletions
+131
-138
src/lib/asiolink/asiodef.cc
src/lib/asiolink/asiodef.cc
+8
-8
src/lib/asiolink/asiodef.h
src/lib/asiolink/asiodef.h
+1
-1
src/lib/asiolink/asiodef.msg
src/lib/asiolink/asiodef.msg
+7
-7
src/lib/asiolink/io_fetch.cc
src/lib/asiolink/io_fetch.cc
+63
-86
src/lib/asiolink/tcp_socket.h
src/lib/asiolink/tcp_socket.h
+1
-1
src/lib/asiolink/tests/io_fetch_unittest.cc
src/lib/asiolink/tests/io_fetch_unittest.cc
+49
-33
src/lib/asiolink/tests/tcp_socket_unittest.cc
src/lib/asiolink/tests/tcp_socket_unittest.cc
+2
-2
No files found.
src/lib/asiolink/asiodef.cc
View file @
f4b20fc5
// File created from asiodef.msg on
Thu Feb 24 11:52:42
2011
// File created from asiodef.msg on
Mon Feb 28 17:15:30
2011
#include <cstddef>
#include <cstddef>
#include <log/message_types.h>
#include <log/message_types.h>
...
@@ -20,14 +20,14 @@ extern const isc::log::MessageID ASIO_UNKRESULT = "UNKRESULT";
...
@@ -20,14 +20,14 @@ extern const isc::log::MessageID ASIO_UNKRESULT = "UNKRESULT";
namespace
{
namespace
{
const
char
*
values
[]
=
{
const
char
*
values
[]
=
{
"FETCHCOMP"
,
"upstream fetch to %s has now completed"
,
"FETCHCOMP"
,
"upstream fetch to %s
(%d)
has now completed"
,
"FETCHSTOP"
,
"upstream fetch to %s has been stopped"
,
"FETCHSTOP"
,
"upstream fetch to %s
(%d)
has been stopped"
,
"OPENSOCK"
,
"error %d opening %s socket to %s"
,
"OPENSOCK"
,
"error %d opening %s socket to %s
(%d)
"
,
"RECVSOCK"
,
"error %d reading
data from %s via a %s socket
"
,
"RECVSOCK"
,
"error %d reading
%s data from %s(%d)
"
,
"RECVTMO"
,
"receive timeout while waiting for data from %s"
,
"RECVTMO"
,
"receive timeout while waiting for data from %s
(%d)
"
,
"SENDSOCK"
,
"error %d sending data
to %s via a %s socket
"
,
"SENDSOCK"
,
"error %d sending data
using %s to %s(%d)
"
,
"UNKORIGIN"
,
"unknown origin for ASIO error code %d (protocol: %s, address %s)"
,
"UNKORIGIN"
,
"unknown origin for ASIO error code %d (protocol: %s, address %s)"
,
"UNKRESULT"
,
"unknown result (%d) when IOFetch::stop() was executed for I/O to %s"
,
"UNKRESULT"
,
"unknown result (%d) when IOFetch::stop() was executed for I/O to %s
(%d)
"
,
NULL
NULL
};
};
...
...
src/lib/asiolink/asiodef.h
View file @
f4b20fc5
// File created from asiodef.msg on
Thu Feb 24 11:52:42
2011
// File created from asiodef.msg on
Mon Feb 28 17:15:30
2011
#ifndef __ASIODEF_H
#ifndef __ASIODEF_H
#define __ASIODEF_H
#define __ASIODEF_H
...
...
src/lib/asiolink/asiodef.msg
View file @
f4b20fc5
...
@@ -15,32 +15,32 @@
...
@@ -15,32 +15,32 @@
$PREFIX ASIO_
$PREFIX ASIO_
$NAMESPACE asiolink
$NAMESPACE asiolink
FETCHCOMP upstream fetch to %s has now completed
FETCHCOMP upstream fetch to %s
(%d)
has now completed
+ A debug message, this records the the upstream fetch (a query made by the
+ A debug message, this records the the upstream fetch (a query made by the
+ resolver on behalf of its client) to the specified address has completed.
+ resolver on behalf of its client) to the specified address has completed.
FETCHSTOP upstream fetch to %s has been stopped
FETCHSTOP upstream fetch to %s
(%d)
has been stopped
+ An external component has requested the halting of an upstream fetch. This
+ An external component has requested the halting of an upstream fetch. This
+ is an allowed operation, and the message should only appear if debug is
+ is an allowed operation, and the message should only appear if debug is
+ enabled.
+ enabled.
OPENSOCK error %d opening %s socket to %s
OPENSOCK error %d opening %s socket to %s
(%d)
+ The asynchronous I/O code encountered an error when trying to open a socket
+ The asynchronous I/O code encountered an error when trying to open a socket
+ of the specified protocol in order to send a message to the target address.
+ of the specified protocol in order to send a message to the target address.
+ The the number of the system error that cause the problem is given in the
+ The the number of the system error that cause the problem is given in the
+ message.
+ message.
RECVSOCK error %d reading
data from %s via a %s socket
RECVSOCK error %d reading
%s data from %s(%d)
+ The asynchronous I/O code encountered an error when trying read data from
+ The asynchronous I/O code encountered an error when trying read data from
+ the specified address on the given protocol. The the number of the system
+ the specified address on the given protocol. The the number of the system
+ error that cause the problem is given in the message.
+ error that cause the problem is given in the message.
SENDSOCK error %d sending data
to %s via a %s socket
SENDSOCK error %d sending data
using %s to %s(%d)
+ The asynchronous I/O code encountered an error when trying send data to
+ The asynchronous I/O code encountered an error when trying send data to
+ the specified address on the given protocol. The the number of the system
+ the specified address on the given protocol. The the number of the system
+ error that cause the problem is given in the message.
+ error that cause the problem is given in the message.
RECVTMO receive timeout while waiting for data from %s
RECVTMO receive timeout while waiting for data from %s
(%d)
+ An upstream fetch from the specified address timed out. This may happen for
+ An upstream fetch from the specified address timed out. This may happen for
+ any number of reasons and is most probably a problem at the remote server
+ any number of reasons and is most probably a problem at the remote server
+ or a problem on the network. The message will only appear if debug is
+ or a problem on the network. The message will only appear if debug is
...
@@ -50,7 +50,7 @@ UNKORIGIN unknown origin for ASIO error code %d (protocol: %s, address %s)
...
@@ -50,7 +50,7 @@ UNKORIGIN unknown origin for ASIO error code %d (protocol: %s, address %s)
+ This message should not appear and indicates an internal error if it does.
+ This message should not appear and indicates an internal error if it does.
+ Please enter a bug report.
+ Please enter a bug report.
UNKRESULT unknown result (%d) when IOFetch::stop() was executed for I/O to %s
UNKRESULT unknown result (%d) when IOFetch::stop() was executed for I/O to %s
(%d)
+ The termination method of the resolver's upstream fetch class was called with
+ The termination method of the resolver's upstream fetch class was called with
+ an unknown result code (which is given in the message). This message should
+ an unknown result code (which is given in the message). This message should
+ not appear and may indicate an internal error. Please enter a bug report.
+ not appear and may indicate an internal error. Please enter a bug report.
src/lib/asiolink/io_fetch.cc
View file @
f4b20fc5
...
@@ -57,17 +57,17 @@ isc::log::Logger logger("asio");
...
@@ -57,17 +57,17 @@ isc::log::Logger logger("asio");
/// \brief IOFetch Data
/// \brief IOFetch Data
///
///
/// The data for IOFetch is held in a separate struct pointed to by a
/// The data for IOFetch is held in a separate struct pointed to by a
shared_ptr
///
shared_ptr object. This is because the IOFetch object will be copi
ed
///
object. This is because the IOFetch object will be copied often (it is us
ed
///
often (it is used as a coroutine and passed as callback to many
///
as a coroutine and passed as callback to many async_*() functions) and we
///
async_*() functions) and we want keep the same data). Organising the
///
want keep the same data). Organising the data in this way keeps copying to
///
data in this way keeps copying to
a minimum.
/// a minimum.
struct
IOFetchData
{
struct
IOFetchData
{
// The first two members are shared pointers to a base class because what is
// The first two members are shared pointers to a base class because what is
// actually instantiated depends on whether the fetch is over UDP or TCP,
// actually instantiated depends on whether the fetch is over UDP or TCP,
// which is not known until construction of the IOFetch. Use of a shared
// which is not known until construction of the IOFetch. Use of a shared
//pointer here is merely to ensure deletion when the data object is deleted.
//
pointer here is merely to ensure deletion when the data object is deleted.
boost
::
shared_ptr
<
IOAsioSocket
<
IOFetch
>
>
socket
;
boost
::
shared_ptr
<
IOAsioSocket
<
IOFetch
>
>
socket
;
///< Socket to use for I/O
///< Socket to use for I/O
boost
::
shared_ptr
<
IOEndpoint
>
remote
;
///< Where the fetch was sent
boost
::
shared_ptr
<
IOEndpoint
>
remote
;
///< Where the fetch was sent
...
@@ -80,23 +80,29 @@ struct IOFetchData {
...
@@ -80,23 +80,29 @@ struct IOFetchData {
bool
stopped
;
///< Have we stopped running?
bool
stopped
;
///< Have we stopped running?
asio
::
deadline_timer
timer
;
///< Timer to measure timeouts
asio
::
deadline_timer
timer
;
///< Timer to measure timeouts
int
timeout
;
///< Timeout in ms
int
timeout
;
///< Timeout in ms
IOFetch
::
Origin
origin
;
///< Origin of last asynchronous I/O
// In case we need to log an error, the origin of the last asynchronous
// I/O is recorded. To save time and simplify the code, this is recorded
// as the ID of the error message that would be generated if the I/O failed.
// This means that we must make sure that all possible "origins" take the
// same arguments in their message in the same order.
isc
::
log
::
MessageID
origin
;
///< Origin of last asynchronous I/O
/// \brief Constructor
/// \brief Constructor
///
///
/// Just fills in the data members of the IOFetchData structure
/// Just fills in the data members of the IOFetchData structure
///
///
/// \param protocol Either IOFetch::TCP or IOFetch::UDP
/// \param protocol Either IOFetch::TCP or IOFetch::UDP
.
/// \param service I/O Service object to handle the asynchronous
/// \param service I/O Service object to handle the asynchronous
/// operations.
///
operations.
/// \param query DNS question to send to the upstream server.
/// \param query DNS question to send to the upstream server.
/// \param address IP address of upstream server
/// \param address IP address of upstream server
/// \param port Port to use for the query
/// \param port Port to use for the query
/// \param buff Output buffer into which the response (in wire format)
/// \param buff Output buffer into which the response (in wire format)
/// is written (if a response is received).
///
is written (if a response is received).
/// \param cb Callback object containing the callback to be called
/// \param cb Callback object containing the callback to be called
/// when we terminate. The caller is responsible for managing this
///
when we terminate. The caller is responsible for managing this
/// object and deleting it if necessary.
///
object and deleting it if necessary.
/// \param wait Timeout for the fetch (in ms).
/// \param wait Timeout for the fetch (in ms).
///
///
/// TODO: May need to alter constructor (see comment 4 in Trac ticket #554)
/// TODO: May need to alter constructor (see comment 4 in Trac ticket #554)
...
@@ -124,11 +130,10 @@ struct IOFetchData {
...
@@ -124,11 +130,10 @@ struct IOFetchData {
stopped
(
false
),
stopped
(
false
),
timer
(
service
.
get_io_service
()),
timer
(
service
.
get_io_service
()),
timeout
(
wait
),
timeout
(
wait
),
origin
(
IOFetch
::
NONE
)
origin
(
ASIO_UNKORIGIN
)
{}
{}
};
};
/// IOFetch Constructor - just initialize the private data
/// IOFetch Constructor - just initialize the private data
IOFetch
::
IOFetch
(
Protocol
protocol
,
IOService
&
service
,
IOFetch
::
IOFetch
(
Protocol
protocol
,
IOService
&
service
,
...
@@ -145,8 +150,7 @@ IOFetch::IOFetch(Protocol protocol, IOService& service,
...
@@ -145,8 +150,7 @@ IOFetch::IOFetch(Protocol protocol, IOService& service,
void
void
IOFetch
::
operator
()(
asio
::
error_code
ec
,
size_t
length
)
{
IOFetch
::
operator
()(
asio
::
error_code
ec
,
size_t
length
)
{
std
::
cerr
<<
"IOFetch::operator() ["
<<
this
<<
"], origin = "
<<
data_
->
origin
<<
", coroutine = "
<<
get_value
()
<<
"
\n
"
;
if
(
data_
->
stopped
)
{
if
(
data_
->
stopped
)
{
return
;
return
;
}
else
if
(
ec
)
{
}
else
if
(
ec
)
{
...
@@ -161,7 +165,7 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
...
@@ -161,7 +165,7 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
/// declarations.
/// declarations.
{
{
Message
msg
(
Message
::
RENDER
);
Message
msg
(
Message
::
RENDER
);
// TODO: replace with boost::random or some other suitable PRNG
// TODO: replace with boost::random or some other suitable PRNG
msg
.
setQid
(
0
);
msg
.
setQid
(
0
);
msg
.
setOpcode
(
Opcode
::
QUERY
());
msg
.
setOpcode
(
Opcode
::
QUERY
());
...
@@ -178,8 +182,8 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
...
@@ -178,8 +182,8 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
data_
->
remote
->
getAddress
().
toText
());
data_
->
remote
->
getAddress
().
toText
());
}
}
// If we timeout, we stop, which will
shutdown everything
and
// If we timeout, we stop, which will
can cancel outstanding I/Os
and
//
cancel all other attempts to run inside the coroutine
//
shutdown everything.
if
(
data_
->
timeout
!=
-
1
)
{
if
(
data_
->
timeout
!=
-
1
)
{
data_
->
timer
.
expires_from_now
(
boost
::
posix_time
::
milliseconds
(
data_
->
timer
.
expires_from_now
(
boost
::
posix_time
::
milliseconds
(
data_
->
timeout
));
data_
->
timeout
));
...
@@ -188,27 +192,20 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
...
@@ -188,27 +192,20 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
}
}
// Open a connection to the target system. For speed, if the operation
// Open a connection to the target system. For speed, if the operation
// was completed synchronously (i.e. UDP operation) we bypass the yield.
// is synchronous (i.e. UDP operation) we bypass the yield.
data_
->
origin
=
ASIO_OPENSOCK
;
data_
->
origin
=
OPEN
;
if
(
data_
->
socket
->
isOpenSynchronous
())
{
if
(
data_
->
socket
->
isOpenSynchronous
())
{
std
::
cerr
<<
"IOFetch: Opening socket synchronously
\n
"
;
data_
->
socket
->
open
(
data_
->
remote
.
get
(),
*
this
);
data_
->
socket
->
open
(
data_
->
remote
.
get
(),
*
this
);
}
else
{
}
else
{
std
::
cerr
<<
"IOFetch: Opening socket asynchronously and yeilding
\n
"
;
CORO_YIELD
data_
->
socket
->
open
(
data_
->
remote
.
get
(),
*
this
);
CORO_YIELD
data_
->
socket
->
open
(
data_
->
remote
.
get
(),
*
this
);
std
::
cerr
<<
"IOFetch: Resuming after Opening socket asynchronously
\n
"
;
}
}
// Begin an asynchronous send, and then yield. When the send completes
// Begin an asynchronous send, and then yield. When the send completes,
// send completes, we will resume immediately after this point.
// we will resume immediately after this point.
// Note: A TCP message may not be sent in one piece (depends on the
data_
->
origin
=
ASIO_SENDSOCK
;
// implementation in TCP socket). Therefore there may be
data_
->
origin
=
SEND
;
std
::
cerr
<<
"IOFetch: asynchronous send
\n
"
;
CORO_YIELD
data_
->
socket
->
asyncSend
(
data_
->
msgbuf
->
getData
(),
CORO_YIELD
data_
->
socket
->
asyncSend
(
data_
->
msgbuf
->
getData
(),
data_
->
msgbuf
->
getLength
(),
data_
->
remote
.
get
(),
*
this
);
data_
->
msgbuf
->
getLength
(),
data_
->
remote
.
get
(),
*
this
);
std
::
cerr
<<
"IOFetch: resuming after asynchronous send
\n
"
;
// Now receive the response. Since TCP may not receive the entire
// Now receive the response. Since TCP may not receive the entire
// message in one operation, we need to loop until we have received
// message in one operation, we need to loop until we have received
// it. (This can't be done within the asyncReceive() method because
// it. (This can't be done within the asyncReceive() method because
...
@@ -216,30 +213,25 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
...
@@ -216,30 +213,25 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
// we need to yield ... and we *really* don't want to set up another
// we need to yield ... and we *really* don't want to set up another
// coroutine within that method.) So after each receive (and yield),
// coroutine within that method.) So after each receive (and yield),
// we check if the operation is complete and if not, loop to read again.
// we check if the operation is complete and if not, loop to read again.
data_
->
origin
=
RECEIVE
;
data_
->
origin
=
ASIO_RECVSOCK
;
do
{
do
{
std
::
cerr
<<
"IOFetch: asynchronous receive
\n
"
;
CORO_YIELD
data_
->
socket
->
asyncReceive
(
data_
->
data
.
get
(),
CORO_YIELD
data_
->
socket
->
asyncReceive
(
data_
->
data
.
get
(),
static_cast
<
size_t
>
(
MIN_LENGTH
),
data_
->
cumulative
,
static_cast
<
size_t
>
(
MIN_LENGTH
),
data_
->
cumulative
,
data_
->
remote
.
get
(),
*
this
);
data_
->
remote
.
get
(),
*
this
);
data_
->
cumulative
+=
length
;
data_
->
cumulative
+=
length
;
std
::
cerr
<<
"IOFetch: resuming after asynchronous receive
\n
"
;
}
while
(
!
data_
->
socket
->
receiveComplete
(
data_
->
data
.
get
(),
}
while
(
!
data_
->
socket
->
receiveComplete
(
data_
->
data
.
get
(),
data_
->
cumulative
));
data_
->
cumulative
));
// The message is not rendered yet, so we can't print it easily
dlog
(
"Received response from "
+
data_
->
remote
->
getAddress
().
toText
());
/// Copy the answer into the response buffer. (TODO: If the
/// Copy the answer into the response buffer. (TODO: If the
/// OutputBuffer object were made to meet the requirements of
/// OutputBuffer object were made to meet the requirements of
a
///
a MutableBufferSequence, then it could be written to directl
y
///
MutableBufferSequence, then it could be written to directly b
y
///
by async_receive_from() and this additional copy step would
///
async_receive_from() and this additional copy step would be
///
be
unnecessary.)
/// unnecessary.)
data_
->
buffer
->
writeData
(
data_
->
data
.
get
(),
length
);
data_
->
buffer
->
writeData
(
data_
->
data
.
get
(),
length
);
// Finished with this socket, so close it.
// Finished with this socket, so close it.
This will not generate an
data_
->
origin
=
CLOSE
;
// I/O error, but reset the origin to unknown in case we change this.
std
::
cerr
<<
"IOFetch: close
\n
"
;
data_
->
origin
=
ASIO_UNKORIGIN
;
data_
->
socket
->
close
();
data_
->
socket
->
close
();
/// We are done
/// We are done
...
@@ -251,9 +243,8 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
...
@@ -251,9 +243,8 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
// query finishes or when the timer times out. Either way, it sets the
// query finishes or when the timer times out. Either way, it sets the
// "stopped_" flag and cancels anything that is in progress.
// "stopped_" flag and cancels anything that is in progress.
//
//
// As the function may be entered multiple times as things wind down, the
// As the function may be entered multiple times as things wind down, it checks
// stopped_ flag checks if stop() has already been called. If it has,
// if the stopped_ flag is already set. If it is, the call is a no-op.
// subsequent calls are no-ops.
void
void
IOFetch
::
stop
(
Result
result
)
{
IOFetch
::
stop
(
Result
result
)
{
...
@@ -276,24 +267,24 @@ IOFetch::stop(Result result) {
...
@@ -276,24 +267,24 @@ IOFetch::stop(Result result) {
//
//
// Although Logger::debug checks the debug flag internally, doing it
// Although Logger::debug checks the debug flag internally, doing it
// below before calling Logger::debug avoids the overhead of a string
// below before calling Logger::debug avoids the overhead of a string
// conversion in the common paths and in the common case when debug is
// conversion in the common case when debug is not enabled.
// not enabled.
//
//
// TODO: Update testing of stopped_ if threads are used.
// TODO: Update testing of stopped_ if threads are used.
data_
->
stopped
=
true
;
data_
->
stopped
=
true
;
switch
(
result
)
{
switch
(
result
)
{
case
TIME_OUT
:
case
TIME_OUT
:
if
(
logger
.
isDebugEnabled
(
1
))
{
if
(
logger
.
isDebugEnabled
(
1
))
{
logger
.
debug
(
1
,
ASIO_RECVTMO
,
logger
.
debug
(
20
,
ASIO_RECVTMO
,
data_
->
remote
->
getAddress
().
toText
().
c_str
());
data_
->
remote
->
getAddress
().
toText
().
c_str
(),
static_cast
<
int
>
(
data_
->
remote
->
getPort
()));
}
}
break
;
break
;
case
SUCCESS
:
case
SUCCESS
:
if
(
logger
.
isDebugEnabled
(
50
))
{
if
(
logger
.
isDebugEnabled
(
50
))
{
logger
.
debug
(
50
,
ASIO_FETCHCOMP
,
logger
.
debug
(
30
,
ASIO_FETCHCOMP
,
data_
->
remote
->
getAddress
().
toText
().
c_str
());
data_
->
remote
->
getAddress
().
toText
().
c_str
(),
static_cast
<
int
>
(
data_
->
remote
->
getPort
()));
}
}
break
;
break
;
...
@@ -301,13 +292,15 @@ IOFetch::stop(Result result) {
...
@@ -301,13 +292,15 @@ IOFetch::stop(Result result) {
// Fetch has been stopped for some other reason. This is
// Fetch has been stopped for some other reason. This is
// allowed but as it is unusual it is logged, but with a lower
// allowed but as it is unusual it is logged, but with a lower
// debug level than a timeout (which is totally normal).
// debug level than a timeout (which is totally normal).
logger
.
debug
(
10
,
ASIO_FETCHSTOP
,
logger
.
debug
(
1
,
ASIO_FETCHSTOP
,
data_
->
remote
->
getAddress
().
toText
().
c_str
());
data_
->
remote
->
getAddress
().
toText
().
c_str
(),
static_cast
<
int
>
(
data_
->
remote
->
getPort
()));
break
;
break
;
default:
default:
logger
.
error
(
ASIO_UNKRESULT
,
static_cast
<
int
>
(
result
),
logger
.
error
(
ASIO_UNKRESULT
,
static_cast
<
int
>
(
result
),
data_
->
remote
->
getAddress
().
toText
().
c_str
());
data_
->
remote
->
getAddress
().
toText
().
c_str
(),
static_cast
<
int
>
(
data_
->
remote
->
getPort
()));
}
}
// Stop requested, cancel and I/O's on the socket and shut it down,
// Stop requested, cancel and I/O's on the socket and shut it down,
...
@@ -321,9 +314,6 @@ IOFetch::stop(Result result) {
...
@@ -321,9 +314,6 @@ IOFetch::stop(Result result) {
if
(
data_
->
callback
)
{
if
(
data_
->
callback
)
{
(
*
(
data_
->
callback
))(
result
);
(
*
(
data_
->
callback
))(
result
);
}
}
// Mark that stop() has now been called.
}
}
}
}
...
@@ -331,32 +321,19 @@ IOFetch::stop(Result result) {
...
@@ -331,32 +321,19 @@ IOFetch::stop(Result result) {
void
IOFetch
::
logIOFailure
(
asio
::
error_code
ec
)
{
void
IOFetch
::
logIOFailure
(
asio
::
error_code
ec
)
{
// Get information that will be in all messages
// Should only get here with a known error code.
static
const
char
*
PROTOCOL
[
2
]
=
{
"TCP"
,
"UDP"
};
assert
((
data_
->
origin
==
ASIO_OPENSOCK
)
||
const
char
*
prot
=
(
data_
->
remote
->
getProtocol
()
==
IPPROTO_TCP
)
?
(
data_
->
origin
==
ASIO_SENDSOCK
)
||
PROTOCOL
[
0
]
:
PROTOCOL
[
1
];
(
data_
->
origin
==
ASIO_RECVSOCK
)
||
(
data_
->
origin
==
ASIO_UNKORIGIN
));
int
errcode
=
ec
.
value
();
std
::
string
str_address
=
data_
->
remote
->
getAddress
().
toText
();
const
char
*
address
=
str_address
.
c_str
();
switch
(
data_
->
origin
)
{
case
OPEN
:
logger
.
error
(
ASIO_OPENSOCK
,
errcode
,
prot
,
address
);
break
;
case
SEND
:
static
const
char
*
PROTOCOL
[
2
]
=
{
"TCP"
,
"UDP"
};
logger
.
error
(
ASIO_SENDSOCK
,
errcode
,
prot
,
address
);
logger
.
error
(
data_
->
origin
,
break
;
ec
.
value
(),
((
data_
->
remote
->
getProtocol
()
==
IPPROTO_TCP
)
?
case
RECEIVE
:
PROTOCOL
[
0
]
:
PROTOCOL
[
1
]),
logger
.
error
(
ASIO_RECVSOCK
,
errcode
,
prot
,
address
);
data_
->
remote
->
getAddress
().
toText
().
c_str
(),
break
;
static_cast
<
int
>
(
data_
->
remote
->
getPort
()));
default:
logger
.
error
(
ASIO_UNKORIGIN
,
errcode
,
prot
,
address
);
}
}
}
}
// namespace asiolink
}
// namespace asiolink
...
...
src/lib/asiolink/tcp_socket.h
View file @
f4b20fc5
...
@@ -62,7 +62,7 @@ private:
...
@@ -62,7 +62,7 @@ private:
TCPSocket
&
operator
=
(
const
TCPSocket
&
);
TCPSocket
&
operator
=
(
const
TCPSocket
&
);
public:
public:
/// \brief Constructor from an ASIO TCP socket.
/// \brief Constructor from an ASIO TCP socket.
///
///
/// \param socket The ASIO representation of the TCP socket. It is assumed
/// \param socket The ASIO representation of the TCP socket. It is assumed
...
...
src/lib/asiolink/tests/io_fetch_unittest.cc
View file @
f4b20fc5
...
@@ -12,13 +12,14 @@
...
@@ -12,13 +12,14 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// PERFORMANCE OF THIS SOFTWARE.
#include <gtest/gtest.h>
#include <algorithm>
#include <boost/bind.hpp>
#include <cstdlib>
#include <cstdlib>
#include <string>
#include <string>
#include <iostream>
#include <iostream>
#include <string.h>
#include <gtest/gtest.h>
#include <boost/bind.hpp>
#include <asio.hpp>
#include <asio.hpp>
...
@@ -30,6 +31,7 @@
...
@@ -30,6 +31,7 @@
#include <dns/name.h>
#include <dns/name.h>
#include <dns/rcode.h>
#include <dns/rcode.h>
#include <asiolink/asiolink_utilities.h>
#include <asiolink/io_address.h>
#include <asiolink/io_address.h>
#include <asiolink/io_endpoint.h>
#include <asiolink/io_endpoint.h>
#include <asiolink/io_fetch.h>
#include <asiolink/io_fetch.h>
...
@@ -38,6 +40,7 @@
...
@@ -38,6 +40,7 @@
using
namespace
asio
;
using
namespace
asio
;
using
namespace
isc
::
dns
;
using
namespace
isc
::
dns
;
using
namespace
asio
::
ip
;
using
namespace
asio
::
ip
;
using
namespace
std
;
namespace
asiolink
{
namespace
asiolink
{
...
@@ -59,6 +62,7 @@ public:
...
@@ -59,6 +62,7 @@ public:
IOFetch
udp_fetch_
;
///< For UDP query test
IOFetch
udp_fetch_
;
///< For UDP query test
IOFetch
tcp_fetch_
;
///< For TCP query test
IOFetch
tcp_fetch_
;
///< For TCP query test
IOFetch
::
Protocol
protocol_
;
///< Protocol being tested
IOFetch
::
Protocol
protocol_
;
///< Protocol being tested
size_t
cumulative_
;
///< Cumulative data received by "server".
// The next member is the buffer in which the "server" (implemented by the
// The next member is the buffer in which the "server" (implemented by the
// response handler methods in this class) receives the question sent by the
// response handler methods in this class) receives the question sent by the
...
@@ -77,7 +81,8 @@ public:
...
@@ -77,7 +81,8 @@ public:
TEST_PORT
,
result_buff_
,
this
,
100
),
TEST_PORT
,
result_buff_
,
this
,
100
),
tcp_fetch_
(
IOFetch
::
TCP
,
service_
,
question_
,
IOAddress
(
TEST_HOST
),
tcp_fetch_
(
IOFetch
::
TCP
,
service_
,
question_
,
IOAddress
(
TEST_HOST
),
TEST_PORT
,
result_buff_
,
this
,
1000
),
TEST_PORT
,
result_buff_
,
this
,
1000
),
protocol_
(
IOFetch
::
TCP
)
// for initialization - will be changed
protocol_
(
IOFetch
::
TCP
),
// for initialization - will be changed
cumulative_
(
0
)
{
{
// Construct the data buffer for question we expect to receive.
// Construct the data buffer for question we expect to receive.
Message
msg
(
Message
::
RENDER
);
Message
msg
(
Message
::
RENDER
);
...
@@ -140,7 +145,8 @@ public:
...
@@ -140,7 +145,8 @@ public:
// Check that length of the received data and the expected data are
// Check that length of the received data and the expected data are
// identical, then check that the data is identical as well.
// identical, then check that the data is identical as well.
EXPECT_EQ
(
msgbuf_
->
getLength
(),
length
);
EXPECT_EQ
(
msgbuf_
->
getLength
(),
length
);
EXPECT_TRUE
(
memcmp
(
msgbuf_
->
getData
(),
server_buff_
,
length
)
==
0
);
EXPECT_TRUE
(
equal
(
server_buff_
,
(
server_buff_
+
length
-
1
),
static_cast
<
const
uint8_t
*>
(
msgbuf_
->
getData
())));
// Return a message back to the IOFetch object.
// Return a message back to the IOFetch object.
socket
->
send_to
(
asio
::
buffer
(
TEST_DATA
,
sizeof
TEST_DATA
),
*
remote
);
socket
->
send_to
(
asio
::
buffer
(
TEST_DATA
,
sizeof
TEST_DATA
),
*
remote
);
...
@@ -155,10 +161,11 @@ public:
...
@@ -155,10 +161,11 @@ public:
/// \param ec Boost error code, value should be zero.
/// \param ec Boost error code, value should be zero.
void
tcpAcceptHandler
(
tcp
::
socket
*
socket
,
error_code
ec
=
error_code
())
void
tcpAcceptHandler
(
tcp
::
socket
*
socket
,
error_code
ec
=
error_code
())
{
{
std
::
cerr
<<
"TCP Accept Handler
\n
"
;
// Expect that the accept completed without a problem.
EXPECT_EQ
(
0
,
ec
.
value
());
// Expect no error
EXPECT_EQ
(
0
,
ec
.
value
());
// Initiate a read on the socket
// Initiate a read on the socket.
cumulative_
=
0
;
socket
->
async_receive
(
asio
::
buffer
(
server_buff_
,
sizeof
(
server_buff_
)),
socket
->
async_receive
(
asio
::
buffer
(
server_buff_
,
sizeof
(
server_buff_
)),