BIND 10 #1522: Implementatio of isc::server_common::SocketRequestor

BIND 10 Development do-not-reply at isc.org
Fri Dec 23 03:20:53 UTC 2011


#1522: Implementatio of isc::server_common::SocketRequestor
-------------------------------------+-------------------------------------
                   Reporter:         |                 Owner:  UnAssigned
  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:3 jelte]:

 I've taken an initial look at the branch.  I don't think we can
 complete the entire review process (I've not even reviewed all of the
 branch) and I'll be off for a while for holidays, so I've dumped what
 I've found so far without picking up the ticket.

 - First, it didn't compile.  I've fixed it myself and pushed the fix.
 - Second, tests didn't pass for me.  I've also fixed it myself and
   pushed the fix.

 '''socket_request.cc'''

 - 'static' isn't necessary for the constant strings:
 {{{#!c++
 static const std::string CREATOR_SOCKET_OK("1");
 }}}
  (and to be pedantic this use of static is officially deprecated in
  C++)

 - in general, defining non POT object this way is a source of static
   initialization fiasco.  sometimes it can happen to be safe depending
   on how exactly it's used, but I'd generally rather avoid it in the
   first place than making it very sure it's safe.  In this case we
   could either define it as char* and compare them using strcmp() or
   define it via a proxy function:
 {{{#!c++
 const std::string& CREATOR_SOCKET_OK() {
     static const std::string str("1");
     return (str);
 }
 }}}

 - The test failure was because the original code didn't take into
   account the case where sockaddr variants have a "length" member (in
   this case sun_len).  I also suspect there may be some kernel
   implementation that rejects connect()/bind() if this member isn't
   set, so it would be safer if we do this:
 {{{#!c++
 #include <config.h>
 ...
 #ifdef HAVE_SA_LEN
     sock_pass_addr.sun_len = <length>;
 #endif
 }}}

 - I suspect there's a off-by-one bug here:
 {{{#!c++
         if (path.size() > sizeof(sock_pass_addr.sun_path)) {
             isc_throw(SocketError, "Unable to open domain socket " << path
 <<
                                    ": path too long");
         }

         strcpy(sock_pass_addr.sun_path, path.c_str());
 }}}
   Consider the case path.size() == sizeof(sun_path) and where the
   terminating \0 will be written.  (If my guess is correct, tell
   vorner that this proves why it was prudent to add an assert() in the
   `SocketSessionForwarder` constructor:-)

 - If the test doesn't cover the boundary case (I've not checked it),
   I'd add it.

 - createFdShareSocket (maybe some others also) is not exception safe:
   If it throws after creating the socket it will leak.  I'd use
   something like `ScopedSocket` defined n lib/util/io/socketsession.cc
   (latest master).  Maybe we should move it to sockaddr_util.h (and
   rename the file) so that it can be shared by other libraries?

 - I'd avoid C-style cast:
 {{{#!c++
         if (connect(sock_pass_fd,
                     (struct sockaddr *)&sock_pass_addr,
                     len) == -1) {
 }}}
   (btw this code also breaks the style guideline in terms of the
   position of *).  I defined and used a conversion template in
   lib/util/io/sockaddr_util.h.  It's still a kind of fraud for the
   compiler, but IMO still better than C-style cast or
   reinterpret_cast, if only to limit the use of these beasts to cases
   where there is absolutely no other alternative.

 - getSocketFd: In my understanding passed_sock_fd == 0 is a valid
   case.

 '''socket_requester_test.cc'''

 - in create(), the code around strncpy() made me nervous, too,
   although in this case it doesn't seem to have a bug.

 '''dns_server_unittest.cc'''

 This is not for this branch (I guess it's a result of importing #805),
 but the tests didn't pass for me, too.  I needed to add this:
 {{{#!c++
          struct sockaddr_in addr;
 +        memset(&addr, 0, sizeof(addr));
          addr.sin_family = AF_INET;
 }}}

 While looking at it I noticed some other things for this file:
 - some of the above comments apply to this implementation, too:
   exception safety, consideration for sin_len, non plain-old static
   object, unnecessary namescope-level static.
 - I would personally use getaddrinfo to create a sockaddr() to avoid
   this kind of portability issue.
 - I would use IPv6 for testing for future generation software like
   BIND 10 (we could also test IPv4 if we want).
 - technically, passing protocol 0 to socket for AF_INET isn't good:
 {{{#!c++
         int result(socket(AF_INET, type, 0));
 }}}
   If and when DCCP or SCTP is more common this can be ambiguous.

-- 
Ticket URL: <http://bind10.isc.org/ticket/1522#comment:5>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list