BIND 10 #1522: Implementatio of isc::server_common::SocketRequestor
BIND 10 Development
do-not-reply at isc.org
Thu Dec 29 08:53:50 UTC 2011
#1522: Implementatio of isc::server_common::SocketRequestor
-------------------------------------+-------------------------------------
Reporter: | Owner: jelte
vorner | Status: reviewing
Type: task | Milestone:
Priority: | Sprint-20120110
blocker | Resolution:
Component: | Sensitive: 0
Unclassified | Sub-Project: Core
Keywords: | Estimated Difficulty: 0
Defect Severity: N/A | Total Hours: 10
Feature Depending on Ticket: |
Socket creator |
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by jinmei):
Replying to [comment:10 vorner]:
As I reported on the daily call, I'm taking over the ticket so we can
complete the socket creator tasks while Jelte is taking off.
I've re-reviewed the entire branch as a successor implementor, and
made some unrelated cleanups: from 80d9d4f to d8ac471. Most of them
should be trivial and non controversial, but there's one substantial
set of changes: I moved some static/private member functions of
SocketRequestor because they don't need any private information of the
class. I generally believe it's better to implement things outside of
a class if they can reasonably be implemented only via the class's
public interfaces.
> > Hmm, looking at that new code I think there is more of it that is
intended to be used here (or if not intended, at least useful).
> >
> > For now I've went for the path of least resistance, added a close() in
the existing throws. This will still leak if there is any other exception
in that part of the code (or if a new throw is added). But given the
seeming intent of the classes in that socketsession, this functionality
should probably be moved there as well (i.e. why not let
SocketSessionReceiver create and connect to a socket, instead of passing
it an opened one? or perhaps provide both options if there is a use-case
for the existing one)
>
> I don't think anything else there could throw, as these are C calls.
>
> Anyway, would you add a ticket to incorporate the code from the
socketsession, so we don't have some code twice?
>
> > Same as above; for now I left this in here, as is, with a TODO message
(oh the pain, committing code with TODOs).
On looking it further, I guess we should eventually merge the FD
passing part of the socket creator interface and SocketSession
framework (is this what Jelte meant by "functionality should be
moved"? If so, I tend to agree). Both do quite the same things using
pretty low level interfaces, which are generally more error prone and
less portability. So unifying such problematic part makes more sense
than other general cases of reducing duplicates. But that would be
beyond the scope of the initial development of socket creator support.
So I'm okay with deferring it to post release development cycle.
> Still the asterisk on the wrong side of space ;-).
I believe I fixed it and other similar style issues.
> Replying to [comment:9 jelte]:
> > > * The status messages from boss are 2 bytes long, either "0\n" or
"1\n", you seem to take only the one byte.
> >
> > ah, doh, changed.
>
> But you still receive (and test) messages that are "0\0" and "1\0", not
"0\n" and "1\n" (that's a newline, not null-byte). You need to update the
constants, the tests and the buffer for reading should be 3 bytes large,
if you want to compare it with ==.
This should be fixed in 182024b.
> > > * When you send a nonsense instead of send_fd (eg. when it is -2),
can you be sure the socket will be in a consistent state? And that it'll
eat the one wrong byte somehow? Because you seem to use the socket after
that.
> >
> > Well, in a way, reusing it and seeing that the next one does not fail
is a way of testing this. I couldn't really come up with any better way to
test it :)
>
> Well, my reasoning is, if nothing guarantees this should be one byte,
then there'll be system that'll fail (solaris, for example).
>
> And besides, if someone sends nonsense, then it might as well be other
amount of nonsense and the protocol gets completely confused. Is there a
reason for this in practice?
I've not fully understood the issue here. What happens in the -2 case
is the child sends one byte data and it's received in recv_fd() where
one the byte data is received by recvmsg() but since no FD is passed
recv_fd() fails and requestSocket() throws. I don't see how this
makes the subsequent doRequest() fail... That said, I think if
requestSocket() fails due to an unexpected error, it generally cannot
be assumed to be usable anymore and the caller application should
basically terminate the connection (and reopen it if necessary). The
SocketSession framework is designed that way.
If we agree, I'm okay with removing the "doRequest() after failure"
test as the behavior in such a case wouldn't be guaranteed.
I've noticed some other, higher design level things while I looked at
the code more closely. These may not have to be addressed in this
release cycle but I'd like to clarify/revise it especially if we
consider unifying this API/implementation with SocketSession:
- In the current implementation (and probably as a result of the
design) I suspect a socket was passed and could leak if "status" is
bogus. Admittedly this wouldn't normally happen, but such a design
seems to be fragile to me.
- I personally don't think it the best idea to signal the case of
"CREATOR_SOCKET_UNAVAILABLE" by exception. At the very least it
should be specifically separated from other exceptions such as the
one as a result of bogus status data; otherwise, assuming the app
should generally drop the connection on the latter case, we could
drop and re-establish the connection unnecessarily
- I also don't think the interface using magic strings like "0\n" is
clean. As we even already noticed such string manipulation is error
prone. It's also counter intuitive to see the existence of '\n'
(although this might be mitigated by introducing some constant
representation). Also, passing non atomic data like this before
passing fd using sendmsg/recvmsg would cause some tricky failure
modes such as the one mentioned in the first bullet above. I'd
rather use the currently-unused one-byte data that is passed with
the FD using sendmsg/recvmsg.
--
Ticket URL: <http://bind10.isc.org/ticket/1522#comment:11>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list