New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bio_dgram uses recvmsg/sendmsg to retrieve destination and set origin address #5257
base: master
Are you sure you want to change the base?
Conversation
The *BSD patches were tested on a FreeBSD 8.4 machine at ISC.ORG. |
2695456
to
c0fdc34
Compare
A lot of code style issue ... |
@FdaSilvaYY , code style issues aside, the regression tests seem to all fail without any details. Do you have any idea if there is something systematic wrong? "make tests" works for me. |
c0fdc34
to
2df6c9c
Compare
@FdaSilvaYY each patch updated with a run through openssl-format-source. Neither bss_dgram.c nor bio.h were clean before I started, so I included a commit that just fixes them before I edit them. |
Travis is failing with 3 different errors (in different builds):
The Appveyor builds are failing with a version of the last error. |
Don't do that! There is too much "noise" in this patch from the openssl-format-source output. Please back that commit out. If |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Skimmed over some parts (there is a lot of noise due to the openssl-format-source). Also didn't look too closely at the tests yet. But there's probably enough comments here for now already!
crypto/bio/bss_dgram.c
Outdated
#include <arpa/inet.h> | ||
#include <netinet/in.h> | ||
#include <netinet/ip6.h> | ||
#include <netinet/icmp6.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail on non-Unix platforms. Probably this needs to be guarded by appropriate ifdef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way (build-server) on which I can test compile against such a platform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only generally available options we have are travis/appveyor integration via github.
crypto/bio/bss_dgram.c
Outdated
@@ -294,26 +308,262 @@ static void dgram_reset_rcv_timeout(BIO *b) | |||
# endif | |||
} | |||
|
|||
# if defined(HAVE_IP_PKTINFO) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than creating a custom define here, could we not just use __linux__
? Adding new defines to Configure just for this seems quite heavyweight.
crypto/bio/bss_dgram.c
Outdated
mhdr.msg_iov = &iov; | ||
mhdr.msg_iovlen = 1; | ||
|
||
if (dstaddr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: if (dstaddr != NULL)
crypto/bio/bss_dgram.c
Outdated
mhdr.msg_controllen = sizeof(chdr); | ||
} | ||
|
||
pkt_info = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do this in the declaration
crypto/bio/bss_dgram.c
Outdated
struct sockaddr *sa = (struct sockaddr *)BIO_ADDR_sockaddr(&data->peer); | ||
if (data->addr.sa.sa_family == 0) { | ||
dgram_get_sockname(b); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use {}
for just a single line if.
crypto/bio/bss_dgram.c
Outdated
ret = BIO_ADDR_sockaddr_size(&data->addr); | ||
if (ret == 0) { /* never set, retrieve it */ | ||
ret = dgram_get_sockname(b); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove {}
} | ||
|
||
/* FIXME: if num < ret, we will only return part of an address. | ||
That should bee an error, no? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs resolution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not my code actually. Happy to fix this in separate patch.
#include <openssl/bio.h> | ||
#include <netinet/in.h> | ||
#include <sys/socket.h> | ||
#include <unistd.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't work on windows!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I have ifdef the entire test. Not sure what is the best way to test these things on windows.
test/bio_read_test.c
Outdated
BIO *out; | ||
int expected_count = PACKET_COUNT; | ||
|
||
pid_t pid = fork(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fork() doesn't exist on Windows!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mattcaswell, my run of the tests on travis seemed to just die in the middle without any obvious error. I guess AppVeyor builds for Windows?
I also now recall that travis has no IPv6. Not sure what to do about that yet.
I don't want to rewrite this test case with select(), because that will just be more complicated and won't work on Windows anyway. Also, re, //- comments, shouldn't the default flags warn on that if travis builds break on that?
Finally, 90% of the style issues you complain about were introduced by openssl-format-source. So I think that openssl-format-source does not comply to the style guide.
What I did was to run it without any material changes and then commit those as on their own so that my changes would be not obscured by indent changes. Why is it wrong to fix bss_dgram.c and bio.h's indented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess AppVeyor builds for Windows?
Yes
I also now recall that travis has no IPv6. Not sure what to do about that yet.
Possibly if we can't create the sockets then we skip that bit of the test - but don't fail it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, re, //- comments, shouldn't the default flags warn on that if travis builds break on that?
The default flags are designed for the general user - not people developing patches. OpenSSL has to run on lots of different platforms with lots of different compilers. We don't run the default with too high warning options because that will introduce spurious build failures for the general user. If you are developing patches you should use --strict-warnings
as mentioned in the CONTRIBUTING file.
Finally, 90% of the style issues you complain about were introduced by openssl-format-source. So I think that openssl-format-source does not comply to the style guide.
Probably it doesn't. The style has developed further since that was written. I wouldn't recommend using it myself. As I said above I would back out those changes.
Why is it wrong to fix bss_dgram.c and bio.h's indented?
It generates a lot of noise and makes it difficult to review the patch (difficult to distinguish your changes from auto-generated changes). If we want to fix large amounts of the formatting in files it should be done in a dedicated PR. Localised fixes are ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the patch that just ran openssl-format-source on that code.
2df6c9c
to
baf995a
Compare
baf995a
to
5756804
Compare
49cce69
to
2166e8c
Compare
https://travis-ci.org/openssl/openssl/jobs/350967905 Operating system: x86_64-whatever-linux2 /usr/bin/env __CNF_CPPDEFINES='' __CNF_CPPINCLUDES='' __CNF_CPPFLAGS='' __CNF_CFLAGS='' __CNF_CXXFLAGS='' __CNF_LDFLAGS='' __CNF_LDLIBS='' /usr/bin/perl ./Configure linux-x86_64 'no-asm' '-Werror' '--debug' 'no-afalgeng' 'no-shared' 'enable-crypto-mdebug' 'enable-rc5' 'enable-md2' ***** Mixing env / make variables and additional compiler/linker flags as ***** configure command line option is not permitted. ***** Affected env / make variables: CFLAGS, CXXFLAGS 0.00s$ ./configdata.pm --dump /home/travis/.travis/job_stages: line 57: ./configdata.pm: No such file or directory The command "./configdata.pm --dump" failed and exited with 127 during . |
2166e8c
to
f48d0d9
Compare
Rebase again to pick up fb174fa? |
all green. review comments dealt with. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a general comment there are lots of indentation errors in this PR. I didn't call them out individually. Please always use 4 spaces for indentation. There are numerous cases of a different number of spaces being used, or tab characters being used.
crypto/bio/bss_dgram.c
Outdated
#else | ||
#include <sys/socket.h> | ||
#include <netinet/in.h> | ||
#include <netinet/ip6.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to be able handle non-windows and non-unix/linux targets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This remains an issue. It's unclear to me whether all of these headers will be available on all platforms. At least in some files we wrap some of these in an "ifdef OPENSSL_SYS_UNIX". We have, as yet, never used netinet/ip6.h - so I am concerned it may not be universally available on all the platforms that we might need to support.
crypto/bio/bss_dgram.c
Outdated
BIO_ADDR *dstaddr, BIO_ADDR *peer) | ||
{ | ||
int len = 0; | ||
unsigned char chdr[BIO_CMSG_ADDR_SIZE]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too many spaces
crypto/bio/bss_dgram.c
Outdated
if(dstaddr != NULL) { | ||
memset(chdr, 0, sizeof(chdr)); | ||
cmsg = (struct cmsghdr *) chdr; | ||
mhdr.msg_control = (void *) cmsg; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: no space between variable and cast in above two lines
crypto/bio/bss_dgram.c
Outdated
val = 1; | ||
if(setsockopt(b->num, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)) < 0) { | ||
return -1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: No {} around a single line if
crypto/bio/bss_dgram.c
Outdated
{ | ||
if (cmsg->cmsg_level != IPPROTO_IP) | ||
continue; | ||
switch(cmsg->cmsg_type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch seems an odd choice when there is only one case
crypto/bio/bss_dgram.c
Outdated
mhdr.msg_iovlen = 1; | ||
|
||
srcaddr = (struct sockaddr_in *)BIO_ADDR_sockaddr(&data->addr); | ||
if(srcaddr && srcaddr->sin_addr.s_addr != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use srcaddr != NULL
struct cmsghdr *cmsg; | ||
struct iovec iov; | ||
char chdr[BIO_CMSG_PKT6_SIZE]; | ||
bio_dgram_data *data = (bio_dgram_data *)b->ptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blank line between declarations and code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is still relevant
test/bio_read_test.c
Outdated
} | ||
#if 0 | ||
printf("bound to port: %u\n", ntohs(localhost.sin_port)); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this
|
||
if(ret <= 0) { | ||
test_printf_stderr("BIO_read returned %d\n", ret); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No {} around single line if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment still relevant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please use TEST_info
for informational messages.
#include <openssl/bio.h> | ||
#include <openssl/rand.h> | ||
#include <openssl/bio.h> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should be using the test framework more fully, i.e. using the TEST_ macros as defined in testutil.h. Take a look at the other tests for examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is still relevant.
Thank you for the patience with my style challenges.
Every project has different demands...
mattcaswell <notifications@github.com> wrote:
We still need to be able handle non-windows and non-unix/linux targets.
which ones specifically, and how can I test on them?
+ switch(cmsg->cmsg_type) {
switch seems an odd choice when there is only one case
yes, perhaps, until one adds another second item.
I feel that this is stylistically what people expect to see when processing
a the control messages. But, I will change it.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
In crypto/bio/bss_dgram.c:
> + iov.iov_base = (caddr_t) in;
+
+ memset(&mhdr, 0, sizeof(mhdr));
+ mhdr.msg_name = (caddr_t)BIO_ADDR_sockaddr(peer);
+ mhdr.msg_namelen = sizeof(struct sockaddr_in);
+ mhdr.msg_iov = &iov;
+ mhdr.msg_iovlen = 1;
+
+ if(dstaddr != NULL) {
+ memset(chdr, 0, sizeof(chdr));
+ cmsg = (struct cmsghdr *) chdr;
+ mhdr.msg_control = (void *) cmsg;
+ mhdr.msg_controllen = sizeof(chdr);
+ }
+
+ if((len = recvmsg(b->num, &mhdr, 0)) >= 0) {
Perhaps add && dstaddr != NULL in this expression?
No, because if the caller didn't set dstaddr, then they aren't interested in
it having it returned. The message should still be retrieved.
In crypto/bio/bss_dgram.c:
> + iov.iov_base = (caddr_t) in;
+
+ memset(&mhdr, 0, sizeof(mhdr));
+ mhdr.msg_name = (caddr_t)BIO_ADDR_sockaddr(peer);
+ mhdr.msg_namelen = sizeof(struct sockaddr_in);
+ mhdr.msg_iov = &iov;
+ mhdr.msg_iovlen = 1;
+
+ if(dstaddr != NULL) {
+ memset(chdr, 0, sizeof(chdr));
+ cmsg = (struct cmsghdr *) chdr;
+ mhdr.msg_control = (void *) cmsg;
+ mhdr.msg_controllen = sizeof(chdr);
+ }
+
+ dstaddr = NULL;
Why are you doing this?
It's wrong, I have removed it. Thank you for noticing.
In crypto/bio/bss_dgram.c:
> + /* see if we found something */
+ if(pkt_info != NULL && dstaddr != NULL) {
+ dstaddr->s_in.sin_family = AF_INET;
+ dstaddr->s_in.sin_addr = pkt_info->ipi_addr;
+ }
+ }
+
+ /* NOTE: peer was filled in by kernel */
+ return len;
+}
+#elif defined(HAVE_IP_RECVDSTADDR)
+/* FREEBSD, DragonFly, NetBSD, OpenBSD, probably BSDi */
+/* implies IP_SENDSRCADDR is available too */
+static int dgram_read_unconnected_v4(BIO *b, const char *in, int inl,
+ int flags,
+ BIO_ADDR *dstaddr, BIO_ADDR *peer)
This function seems to be almost identical to the once above with only minor
differences. Can't we combine the two and just have guards around the bits
which are different?
Once the differences in declarations are accounted for with #ifdefs or
macros somewhere, it seems to me that the flow will be impacted such that
observations like the one that you made above would not be seen.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
In crypto/bio/bss_dgram.c:
> + mhdr.msg_iov = &iov;
+ mhdr.msg_iovlen = 1;
+
+ if(dstaddr != NULL) {
+ memset(chdr, 0, sizeof(chdr));
+ cmsg = (struct cmsghdr *) chdr;
+ mhdr.msg_control = (void *) cmsg;
+ mhdr.msg_controllen = sizeof(chdr);
+ }
+
+ dstaddr = NULL;
+ if((len = recvmsg(b->num, &mhdr, 0)) >= 0) {
+ for (cmsg = CMSG_FIRSTHDR(&mhdr);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&mhdr, cmsg))
+ {
{ goes on the end of the previous line
ok.
+#endif
+
+/* on Windows, RFC3542 is not implemented correctly, instead
+ * WSARecvMsg must be used rather than recvmsg
But you don't seem to use that below?
No, I have not the skill or equipment to implement that.
+static int dgram_get_sockname(BIO *b)
+{
+ bio_dgram_data *data = NULL;
+ socklen_t addr_len = sizeof(bio_dgram_data);
+
+ data = (bio_dgram_data *)b->ptr;
Do this initialisation in the declaration of data above.
done.
+ srcaddr = (struct sockaddr_in *)BIO_ADDR_sockaddr(&data->addr);
+ if(srcaddr && srcaddr->sin_addr.s_addr != 0) {
+ struct in_pktinfo *pkt_info;
+ memset(chdr, 0, sizeof(chdr));
Add blank line between declarations and start of code
done.
+ cmsg = CMSG_FIRSTHDR(&mhdr);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
Too many spaces
I was aligning the assignments up, but if that's not something you like, then
I'll fix them all.
+#if 0
+ printf("controllen: %d\n", mhdr.msg_controllen);
+#endif
Please remove this
done.
+ /* CMSG_SOCKET is from sys/socket.h, and makes
+ * space for a cmsghdr as well as alignment
+ */
+ char chdr[BIO_CMSG_ADDR_SIZE];
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
Blank line between declarations and code
done.
+ struct sockaddr_in *srcaddr;
+ struct in_addr *origaddr;
Too many spaces
ok.
+ if(srcaddr && srcaddr->sin_addr.s_addr != 0) {
Use srcaddr != NULL
done.
+#endif
+
+#if defined(AF_INET6) && !defined(_WIN32)
+static int dgram_write_unconnected_v6(BIO *b, const char *out, int outl)
+{
+ struct sockaddr_in6 addr;
+ struct sockaddr_in6 *srcaddr;
+ struct msghdr mhdr;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ char chdr[BIO_CMSG_PKT6_SIZE];
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
Blank line between declarations and code
it's all declarations.
In test/bio_read_test.c:
+#if 0
+ printf("bound to port: %u\n", ntohs(localhost.sin_port));
+#endif
Remove this
done.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
In test/bio_read_test.c:
> +
+ ba = BIO_ADDR_new();
+
+ in = BIO_new_dgram(fd, BIO_CLOSE);
+
+ while(--count > 0 && (ret=BIO_read(in, buf, 512))>0) {
+
+ /* now check out the bio structure for the origin of the packet */
+ BIO_get_dgram_origin(in, ba);
+ port = ntohs(BIO_ADDR_rawport(ba));
+ if(port!=0 && port != portnum) { exit(5); }
+ }
+
+ if(ret <= 0) {
+ test_printf_stderr("BIO_read returned %d\n", ret);
+ }
No {} around single line if
ok.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
In test/bio_write_test.c:
> @@ -0,0 +1,228 @@
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+
This file should be using the test framework more fully, i.e. using the TEST_
macros as defined in testutil.h. Take a look at the other tests for examples.
Are saying something like:
TEST_int_ne(count, 0);
rather than:
if(count != 0) {
test_printf_stderr("failed receive all packets: %d\n", count);
exit(2);
}
if so I will see what I can in another commit.
This email will likely arrive before I have a chance to push any code.
|
…nation address seen
Includes a test case to write packets using the interface.
…_PKTINFO, and set this option generically on Linux
…his author. Make sure it compiles on Windows using recvfrom()/sendto() instead
…tainers have IPv6 disabled (not even a loopback) so no IPv6 tests will function, turn off IPv6 version of bio_write_test and bio_read_test
not have SENDDSTADDR for IPv4. RFC 3542 needs to be explicitely enabled with a #define clang does not believe that Darwin CMSG_SPACE is a constant and issues warning
371fea6
to
3567dbb
Compare
crypto/bio/bss_dgram.c
Outdated
# if OPENSSL_USE_IPV6 | ||
# if OPENSSL_SYS_WINDOWS | ||
# include "shared/netiodef.h> | ||
# else | ||
# include <netinet/ip6.h> | ||
# endif | ||
# endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Referring to your discussion with Michael Wojcik:
> > #if defined OPENSSL_SYS_WINDOWS
> > # include <shared/netiodef.h>
> > #else
> > # include <netinet/ip6.h>
> > #endif
>
> But, don't all the OPENSSL_* macros expand to 0/1, anyway, so we actually
> just want #if OPENSSL_SYS_WINDOWS?
In principle, you might be right, but in practice a quick git grep OPENSSL_SYS
will convince you that everywhere throughout the OpenSSL source code we use either #ifdef OPENSSL_SYS*
or #if defined(OPENSSL_SYS*)
and not #if OPENSSL_SYS*
. So for consistency reasons I ask you to please change it.
(The OPENSSL_USE_IPV6
macro unfortunately has a different semantics (see a5a0f32), here you should keep the #if
. So much for consistency :-/ )
a8ac8b5
to
7a1934a
Compare
… when dgram is disabled
7a1934a
to
d8c3d89
Compare
This code and two test cases adjusts the bss_dgram read/write which is used in DTLS such that
the originating and destination addresses are retrieved upon read, and are set in write. This permits
a UDP "server" socket to be bound to :: (0.0.0.0) and receive traffic to any interface on the machine.
This code includes IP_PKTINFO (v4) for Linux, and IP_RECVDSTADDR/IP_SENDSRCADDR (v4) for *BSD, and if not falls back to recvfrom/sendto(). For IPv6, it is assumed that the stock IETF APIs
using pktinfo are available. The choice of PKTINFO or RECVDSTADDR is determined by the Configure scripts.
These patches include four additional BIO_crtl messages to set/get the origin/dest address from the BIO.
There was previous concern about CMSG_SPACE() being constant or not; but the specifications say that those macros are guaranteed to be compile time constants.
In addition, code to enable IP_PKTINFO and IPV6_PKTINFO on OSX is included. OSX has RECDSTADDR (like other BSDs), but does not have SENDSRCADDR. IP_PKTINFO was added in OSX 10.9, prior versions may need to disable both IP_PKTINFO and IP_RECVDSTADDR.