BIND 10 #1452: add UDP socket passing to fd_X handling
BIND 10 Development
do-not-reply at isc.org
Fri Dec 16 16:16:37 UTC 2011
#1452: add UDP socket passing to fd_X handling
-------------------------------------+-------------------------------------
Reporter: jelte | Owner: jinmei
Type: task | Status: reviewing
Priority: major | Milestone:
Component: DDNS | Sprint-20111220
Keywords: | Resolution:
Defect Severity: N/A | Sensitive: 0
Feature Depending on Ticket: DDNS | Sub-Project: DNS
Add Hours to Ticket: 0 | Estimated Difficulty: 5
Internal?: 0 | Total Hours: 0
-------------------------------------+-------------------------------------
Changes (by vorner):
* owner: vorner => jinmei
Comment:
Hello
Replying to [comment:5 jinmei]:
> Unfortunately the diff is pretty large. Basically, however, (I hope)
> it only does some straightforward things. But the resulting code was
> this big due to the need for considering various corner cases and
> providing detailed tests. My suggestion for review is to first read
> the overview doxygen documentation in util/io/socketsssion.h (in the
> `SocketSessionUtility` page), then look at the ForwardTest::pushAndPop
> test (in util/tests/socketsession_unittest.cc), which checks basic
> expected behaviors, along with the corresponding implementation.
It's quite OK to keep in mind, even when large code-wise.
But there are some problems with the branch.
First, the library now uses exceptions, so it must link to it. I pushed a
makefile fix, so it now compiles for me.
The tests fail for me:
{{{
[ RUN ] ForwardTest.pushTooFast
socketsession_unittest.cc:685: Failure
Expected: multiPush(forwarder_, *getSockAddr("192.0.2.1", "53").first,
large_text_.c_str(), large_text_.length()) throws an exception of type
SocketSessionError.
Actual: it throws nothing.
[ FAILED ] ForwardTest.pushTooFast (0 ms)
}}}
My guess for this is, linux takes the buffer size as some kind of hint
only and makes its own mind about the proper size and 3 messages fit
without a problem. If I increased it to 3000, the test passed, I didn't
test when it started to pass and I'm not sure if it might be dependant on
some system parameters (amount of memory, size of memory management pages,
etc).
Also, is the „receptor“ name a good one? It reminds me with the little
parts of cells that detect which chemicals are around and what temperature
it is. Shouldn't it be a „recipient“, for the one who receives?
I'm not sure about how the blocking reads are used and such. For one, if
there comes three messages to be forwarded at once and they are all
handled by auth before a single context switch happens, the last one would
get dropped, even if the system would be completely capable of handling
the load. Also, I heard some system (linux is one of them) can cause a
spurious wakeup on a select for a socket that has no data to read. I'm not
sure if it can be with a local socket, or if it was a result of some
packet that came for the connection but was corrupt, or something. Anyway,
it is probably good enough for now, if we're considering to do it
differently with the receptionist (I'd very like to have auth, xfrin,
xfrout and ddns blocking then, using only single connection to the
receptionist).
Also, there are several mostly minor issues:
* Should the SA_TYPE in template be upper case? Don't we use it for
constants and enum values? This is type, so it should be CamelCase:
{{{#!c++
template <typename SA_TYPE>
}}}
* Should we use cerrno instead of errno.h? The same applies for stdint.h
and string.h.
* Should the local includes be done first, before other headers, to
ensure they don't use something from the system headers included above?
* Should this use `UNIX_MATH_PATH` instead?
{{{#!c++
(sizeof(impl.sock_un_.sun_path) - 1 < unix_file.length())
}}}
* If you already check the size, why do you use the (more complicated)
strncpy instead of strcpy? Is there a trick I'm forgetting?
{{{#!c++
strncpy(impl.sock_un_.sun_path, unix_file.c_str(),
sizeof(impl.sock_un_.sun_path));
}}}
* I don't see why the „rest“ of the buffer with the path should be
zeroed. The strncpy will zero only one byte after the end of string, and
this might be far after it. I don't see anything zeroing it anywhere, so
it might contain quite anything what was on the stack:
{{{#!c++
assert(impl.sock_un_.sun_path[sizeof(impl.sock_un_.sun_path) - 1] ==
'\0');
}}}
* Where does the magic number „2“ come from here?
{{{#!c++
impl.sock_un_len_ = 2 + unix_file.length();
}}}
* Should the right side be impl.sock_un_len_? Nobody anywhere assigned to
sock_un_len_ and I don't see it anywhere.
{{{#!c++
#ifdef HAVE_SA_LEN
impl.sock_un_.sun_len = sock_un_len_;
#endif
}}}
* As described in the man page (The freeaddrinfo() function frees the
memory that was allocated for the dynamically allocated linked list res.),
the freeaddrinfo should be called only once on the whole result ‒ it frees
the whole list, not on each of the nodes there. I guess there was no
problem here, as it produces only single-element lists here, but it's
needlessly complicated and, in principle, wrong, as it may create double-
free errors.
With regards
--
Ticket URL: <http://bind10.isc.org/ticket/1452#comment:8>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list