diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2014-04-23 20:59:37 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2014-04-23 20:59:37 +0000 |
commit | 0490b302b088b1c02c68a11bcd9abab82297160a (patch) | |
tree | f692201852290c042b31065f9e3859027c2ada3c /lib/libcrypto/bio/b_sock.c | |
parent | 2e5f2b640961a8a3dc1733d2b1ffe7abe871e5fa (diff) |
The usual idiom to cope with systems not defining socklen_t is to add a
#define socklen_t int
somewhere (or a typedef, whatever gives you an integer type of the size
your system expects as the 3rd argument of accept(2), really).
OpenSSL here is a bit more creative by using an union of an int and a size_t,
and extra code if sizeof(int) != sizeof(size_t) in order to recover the
proper size. With a comment mentioning that this has no chance to work on
a platform with a stack growing up and accept() returning an int, fortunately
this seems to work on HP-UX.
Switch to the light side of the force and declare and use socklen_t variables,
period. If your system does not define socklen_t, consider bringing it back
to your vendor for a refund.
ok matthew@ tedu@
Diffstat (limited to 'lib/libcrypto/bio/b_sock.c')
-rw-r--r-- | lib/libcrypto/bio/b_sock.c | 40 |
1 files changed, 5 insertions, 35 deletions
diff --git a/lib/libcrypto/bio/b_sock.c b/lib/libcrypto/bio/b_sock.c index e5f42398df6..05eb362cc6d 100644 --- a/lib/libcrypto/bio/b_sock.c +++ b/lib/libcrypto/bio/b_sock.c @@ -452,31 +452,7 @@ BIO_accept(int sock, char **addr) char *p, *tmp; struct { - /* - * As for following union. Trouble is that there are platforms - * that have socklen_t and there are platforms that don't, on - * some platforms socklen_t is int and on some size_t. So what - * one can do? One can cook #ifdef spaghetti, which is nothing - * but masochistic. Or one can do union between int and size_t. - * One naturally does it primarily for 64-bit platforms where - * sizeof(int) != sizeof(size_t). But would it work? Note that - * if size_t member is initialized to 0, then later int member - * assignment naturally does the job on little-endian platforms - * regardless accept's expectations! What about big-endians? - * If accept expects int*, then it works, and if size_t*, then - * length value would appear as unreasonably large. But this - * won't prevent it from filling in the address structure. The - * trouble of course would be if accept returns more data than - * actual buffer can accomodate and overwrite stack... That's - * where early OPENSSL_assert comes into picture. Besides, the - * only 64-bit big-endian platform found so far that expects - * size_t* is HP-UX, where stack grows towards higher address. - * <appro> - */ - union { - size_t s; - int i; - } len; + socklen_t len; union { struct sockaddr sa; struct sockaddr_in sa_in; @@ -484,15 +460,9 @@ BIO_accept(int sock, char **addr) } from; } sa; - sa.len.s = 0; - sa.len.i = sizeof(sa.from); + sa.len = sizeof(sa.from); memset(&sa.from, 0, sizeof(sa.from)); - ret = accept(sock, &sa.from.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { - OPENSSL_assert(sa.len.s <= sizeof(sa.from)); - sa.len.i = (int)sa.len.s; - /* use sa.len.i from this point */ - } + ret = accept(sock, &sa.from.sa, &sa.len); if (ret == -1) { if (BIO_sock_should_retry(ret)) return -2; @@ -511,7 +481,7 @@ BIO_accept(int sock, char **addr) static union { void *p; int (*f)(const struct sockaddr *, - size_t/*socklen_t*/, char *, size_t, + socklen_t, char *, size_t, char *, size_t, int); } p_getnameinfo = {NULL}; /* 2nd argument to getnameinfo is specified to @@ -527,7 +497,7 @@ BIO_accept(int sock, char **addr) if (p_getnameinfo.p == (void *) - 1) break; - if ((*p_getnameinfo.f)(&sa.from.sa, sa.len.i, h, sizeof(h), + if ((*p_getnameinfo.f)(&sa.from.sa, sa.len, h, sizeof(h), s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV)) break; nl = strlen(h) + strlen(s) + 2; |