[bind10-dev] Socket creator and low-level code
JINMEI Tatuya / 神明達哉
jinmei at isc.org
Thu Oct 21 15:26:45 UTC 2010
At Thu, 21 Oct 2010 09:18:44 +0200,
Michal 'vorner' Vaner <michal.vaner at nic.cz> wrote:
> template<typename T>
> bool
> readVar(int fd, T &variable) {
> return (read_data(fd, &variable, sizeof(typename T)) == sizeof(typename T));
> }
>
> This is much more usable. Does it seem right for you as well, regarding the
> pointer-cleanness and so? It solves even the wrong-length bug and in case
Hmm, I think I can live with that.
But, I'm still not so happy with read_data() manipulating the buffer
with low level pointer arithmetic. I'd suggest either
- using a safe interface such as std::vector if we need to keep the IO
primitive that needs to expect partial read, or
- use a real socket with recv(MSG_WAITALL). then we don't even have
to need a separate read_data function. it can simply be:
return (recv(fd, &variable, sizeof(T), MSG_WAITALL) == sizeof(T));
or
- if we want to keep using stdin and stdout, use std::iostream instead
of the lower level API
> someone would like to send more complicated data structures (like std::string),
> a template-specified function could be written and solve it (thought I doubt
> there will be need for that any time).
std::string won't work with this approach, because passing an address
to an object of std::string is meaningless.
> There are 2 more places where pointers are used. There's memset, because the
> sockaddr_* structures have no constructors. It could be overcome by using a
> global variable (so it is zeroed at the start of program) at the cost of reusing
> it.
I can live with such localized use of memset(0).
> Other place is the interface of BSD sockets, namely bind. I have no idea what to
> do with this. But I use it only as a reference to the correct sockaddr_*
> structure. I maybe should add an assert to ensure it is really set.
This is also okay for me. At interfaces to lowest level system call,
passing a row pointer is inevitable.
Having said that, I would actually propose one different type of
approach, not actually related to the pointer vs higher-level API
discussion.
I wonder whether we can pass addresses and ports as a string, which
will be represented in the form of length + C-string. Then we can use
getaddrinfo(3) to support both IPv4 and IPv6 in unified code, without
worrying about portability of sa_len (btw your current code has this
portability bug). The main drawback of this approach is exchanging
variable-length data may be considered riskier, but, I would accept
that risk if we use safer API.
---
JINMEI, Tatuya
Internet Systems Consortium, Inc.
More information about the bind10-dev
mailing list