Approach to sin_zero

W

woodbrian77

Shalom

Is the memset below needed? Stevens says sin_zero is
not used. Others on the newsgroups say clearing the field
is needed on a few platforms. I've left the memset in just
to be on the safe side.

sock_type cmw::udp_server (uint32_t port)
{
sock_type sd = getSocket(SOCK_DGRAM);
sockaddr_in si_me;
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
::std::memset(&si_me.sin_zero, 0, sizeof(si_me.sin_zero));
if :):bind(sd, (sockaddr*) &si_me, sizeof(si_me))==-1) {
throw failure("udp Bind errno: ") << GetError();
}
return sd;
}

Thanks in advance.

Ebenezer Enterprises -- making programming fun again.
http://webEbenezer.net
 
M

Melzzzzz

On Mon, 8 Oct 2012 18:58:53 -0700 (PDT)
Shalom

Is the memset below needed? Stevens says sin_zero is
not used. Others on the newsgroups say clearing the field
is needed on a few platforms. I've left the memset in just
to be on the safe side.

sock_type cmw::udp_server (uint32_t port)
{
sock_type sd = getSocket(SOCK_DGRAM);
sockaddr_in si_me;
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
::std::memset(&si_me.sin_zero, 0, sizeof(si_me.sin_zero));
if :):bind(sd, (sockaddr*) &si_me, sizeof(si_me))==-1) {
throw failure("udp Bind errno: ") << GetError();
}
return sd;
}

Quick google search shows that on mac OS X it is needed.
Perhaps on Free BSD, too.

Anyway, I always initialize whole struct to zero prior
filling fields ;)
 
I

Ian Collins

Shalom

Is the memset below needed? Stevens says sin_zero is
not used. Others on the newsgroups say clearing the field
is needed on a few platforms. I've left the memset in just
to be on the safe side.

While somewhat OT, a couple of points:
sock_type cmw::udp_server (uint32_t port)
{
sock_type sd = getSocket(SOCK_DGRAM);
sockaddr_in si_me;

Why not just write

sockaddr_in si_me = {0};

and leave it at that?
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);

What happens if post is too big for a uint16_t? In other words, why is
the parameter type a uint32_t?
 
J

Jorgen Grahn

Shalom

Is the memset below needed? Stevens says sin_zero is
not used. Others on the newsgroups say clearing the field
is needed on a few platforms. I've left the memset in just
to be on the safe side.

sock_type cmw::udp_server (uint32_t port)
{
sock_type sd = getSocket(SOCK_DGRAM);
sockaddr_in si_me;
si_me.sin_family = AF_INET;
si_me.sin_port = htons(port);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
::std::memset(&si_me.sin_zero, 0, sizeof(si_me.sin_zero));
if :):bind(sd, (sockaddr*) &si_me, sizeof(si_me))==-1) {
throw failure("udp Bind errno: ") << GetError();
}
return sd;
}

Is there a reason you don't use POSIX getaddrinfo(3)? It handles those
things for you, takes care of IPv4/IPv6, and is described in Stevens'
books.

Followup set.

/Jorgen
 
W

woodbrian77

What happens if post is too big for a uint16_t? In other words, why is

the parameter type a uint32_t?

That's probably laziness and I'll check on
changing it.
 
W

woodbrian77

Is there a reason you don't use POSIX getaddrinfo(3)? It handles those

things for you, takes care of IPv4/IPv6, and is described in Stevens'

books.

I'm using getaddrinfo elsewhere, but it hadn't
occurred to me to use it here.
Followup set.

What does that mean?
 
V

Victor Bazarov

[..]
Followup set.

What does that mean?

That means that if you used a real newsreader, the reply would
automatically be addressed to another newsgroup, in this case
'comp.protocols.tcp-ip', which Jorgen probably recommends for this
discussion (instead of c.l.c++). Of course the newsgroup for the reply
can always be overridden, but it requires conscious effort (IOW using
one's brain)...

V
 
J

Jorgen Grahn

[..]
Followup set.

What does that mean?

That means that if you used a real newsreader, the reply would
automatically be addressed to another newsgroup,

Yes, and I'm surprised that Google ignores it. I knew they were a pain
on Usenet, but not that they were *that* arrogant.

But I should have written "Followup-to set to comp.protocols.tcp-ip"
for clarity.

/Jorgen
 
W

woodbrian77

Here's a version that uses getaddrinfo:

sock_type cmw::udp_server (uint16_t port)
{
::std::eek:stringstream out;
out << port;

addrinfo* res;
addrinfo hints;
::std::memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

int err;
if ((err = ::getaddrinfo(nullptr
, out.str().c_str()
, &hints
, &res
)) != 0) {
throw failure("udp_server getaddrinfo: ") << gai_strerror(err);
}

sock_type sd = getSocket(SOCK_DGRAM);
if :):bind(sd, res->ai_addr, res->ai_addrlen)==-1) {
throw failure("udp_server bind: ") << GetError();
}
return sd;
}

The unfortunate thing is the change adds over 2,000 bytes
to an executable. It isn't a big executable and the
percentage increase is close to 3%. That strikes me as
excessive. Are there any other alternatives?
 
W

woodbrian77

Are there any other alternatives?

Does it work to change

si_me.sin_family = AF_INET;

to

si_me.sin_family = AF_UNSPEC;

in the function I originally posted?

It looks like there are people doing that out there,
but I couldn't find anything that says it is valid.
 
I

Ian Collins

Here's a version that uses getaddrinfo:

sock_type cmw::udp_server (uint16_t port)
{
::std::eek:stringstream out;
out<< port;

addrinfo* res;
addrinfo hints;
::std::memset(&hints, 0, sizeof(hints));

Why do you call memset?

addrinfo hints = {0};

Is more concise.
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

int err;
if ((err = ::getaddrinfo(nullptr
, out.str().c_str()
,&hints
,&res
)) != 0) {
throw failure("udp_server getaddrinfo: ")<< gai_strerror(err);
}

sock_type sd = getSocket(SOCK_DGRAM);
if :):bind(sd, res->ai_addr, res->ai_addrlen)==-1) {
throw failure("udp_server bind: ")<< GetError();
}
return sd;
}

The unfortunate thing is the change adds over 2,000 bytes
to an executable. It isn't a big executable and the
percentage increase is close to 3%. That strikes me as
excessive. Are there any other alternatives?

Try comp.unix.programmer.
 
I

Ian Collins

Does it work to change

si_me.sin_family = AF_INET;

to

si_me.sin_family = AF_UNSPEC;

in the function I originally posted?

It looks like there are people doing that out there,
but I couldn't find anything that says it is valid.

Try comp.unix.programmer.
 
W

woodbrian77

To go a little further with this ... everything seems
to be working fine on Linux. And if the middle tier is
running on Linux and the front tier on Windows things
work fine. But if both the middle and front tiers are
running on Windows, I get a 10054 -- port unreachable
error. I'm not sure if this indicates a problem in the
networking code that I've been working on. If there is
a problem, the above seems to indicate it is with the
middle tier which is a udp server.

addrinfo* cmw::getaddrinfo_wrapper(char const * node
, int port
, int flags
, int socktype
)
{
::std::eek:stringstream out;
out << port;

addrinfo* res;
addrinfo hints = {0};
hints.ai_flags = flags;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = socktype;

int err;
if ((err = ::getaddrinfo(node
, out.str().c_str()
, &hints
, &res
)) != 0) {
throw failure("Getaddrinfo: ") << gai_strerror(err);
}
return res;
}


sock_type cmw::udp_server (uint16_t port)
{
addrinfo* res = getaddrinfo_wrapper(nullptr
, port
, AI_PASSIVE
, SOCK_DGRAM
);
sock_type sd = getSocket(res->ai_family, SOCK_DGRAM);
if :):bind(sd, res->ai_addr, res->ai_addrlen)==-1) {
throw failure("udp_server bind: ") << GetError();
}
::freeaddrinfo(res);
return sd;
}

Netstat on windows shows this
UDP [::]:55555 *:*

which is the port number I expect it to use.

I guess it could be a Windows problem, but am not
really sure. All of the code is here --
http://webEbenezer.net/build_integration.html
..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top