diff options
Diffstat (limited to 'ipsvd/udp_io.c')
-rw-r--r-- | ipsvd/udp_io.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/ipsvd/udp_io.c b/ipsvd/udp_io.c index 68999d44d..2efc15913 100644 --- a/ipsvd/udp_io.c +++ b/ipsvd/udp_io.c | |||
@@ -18,12 +18,13 @@ socket_want_pktinfo(int fd) | |||
18 | #ifdef IP_PKTINFO | 18 | #ifdef IP_PKTINFO |
19 | setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); | 19 | setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); |
20 | #endif | 20 | #endif |
21 | #ifdef IPV6_PKTINFO | 21 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
22 | setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); | 22 | setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); |
23 | #endif | 23 | #endif |
24 | } | 24 | } |
25 | 25 | ||
26 | 26 | ||
27 | #ifdef UNUSED | ||
27 | ssize_t | 28 | ssize_t |
28 | send_to_from(int fd, void *buf, size_t len, int flags, | 29 | send_to_from(int fd, void *buf, size_t len, int flags, |
29 | const struct sockaddr *from, const struct sockaddr *to, | 30 | const struct sockaddr *from, const struct sockaddr *to, |
@@ -34,8 +35,11 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
34 | #else | 35 | #else |
35 | struct iovec iov[1]; | 36 | struct iovec iov[1]; |
36 | struct msghdr msg; | 37 | struct msghdr msg; |
37 | char cbuf[LSA_SIZEOF_SA]; | 38 | char cbuf[sizeof(struct in_pktinfo) |
38 | /* actually, max(sizeof(in_pktinfo),sizeof(in6_pktinfo)) */ | 39 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
40 | | sizeof(struct in6_pktinfo) /* (a|b) is poor man's max(a,b) */ | ||
41 | #endif | ||
42 | ]; | ||
39 | struct cmsghdr* cmsgptr; | 43 | struct cmsghdr* cmsgptr; |
40 | 44 | ||
41 | if (from->sa_family != AF_INET | 45 | if (from->sa_family != AF_INET |
@@ -73,11 +77,11 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
73 | /* pktptr->ipi_ifindex = 0; -- already done by memset(cbuf...) */ | 77 | /* pktptr->ipi_ifindex = 0; -- already done by memset(cbuf...) */ |
74 | pktptr->ipi_spec_dst = ((struct sockaddr_in*)from)->sin_addr; | 78 | pktptr->ipi_spec_dst = ((struct sockaddr_in*)from)->sin_addr; |
75 | } | 79 | } |
76 | #if ENABLE_FEATURE_IPV6 && defined(IP6_PKTINFO) | 80 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
77 | else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) { | 81 | else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) { |
78 | struct in6_pktinfo *pktptr; | 82 | struct in6_pktinfo *pktptr; |
79 | cmsgptr->cmsg_level = IPPROTO_IPV6; | 83 | cmsgptr->cmsg_level = IPPROTO_IPV6; |
80 | cmsgptr->cmsg_type = IP6_PKTINFO; | 84 | cmsgptr->cmsg_type = IPV6_PKTINFO; |
81 | cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); | 85 | cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); |
82 | pktptr = (struct in6_pktinfo *)(CMSG_DATA(cmsgptr)); | 86 | pktptr = (struct in6_pktinfo *)(CMSG_DATA(cmsgptr)); |
83 | /* pktptr->ipi6_ifindex = 0; -- already done by memset(cbuf...) */ | 87 | /* pktptr->ipi6_ifindex = 0; -- already done by memset(cbuf...) */ |
@@ -87,8 +91,12 @@ send_to_from(int fd, void *buf, size_t len, int flags, | |||
87 | return sendmsg(fd, &msg, flags); | 91 | return sendmsg(fd, &msg, flags); |
88 | #endif | 92 | #endif |
89 | } | 93 | } |
94 | #endif /* UNUSED */ | ||
90 | 95 | ||
91 | /* NB: this will never set port# in *to! */ | 96 | /* NB: this will never set port# in 'to'! |
97 | * _Only_ IP/IPv6 address part of 'to' is _maybe_ modified. | ||
98 | * Typical usage is to preinit it with "default" value | ||
99 | * before calling recv_from_to(). */ | ||
92 | ssize_t | 100 | ssize_t |
93 | recv_from_to(int fd, void *buf, size_t len, int flags, | 101 | recv_from_to(int fd, void *buf, size_t len, int flags, |
94 | struct sockaddr *from, struct sockaddr *to, | 102 | struct sockaddr *from, struct sockaddr *to, |
@@ -123,7 +131,6 @@ recv_from_to(int fd, void *buf, size_t len, int flags, | |||
123 | return recv_length; | 131 | return recv_length; |
124 | 132 | ||
125 | /* Here we try to retrieve destination IP and memorize it */ | 133 | /* Here we try to retrieve destination IP and memorize it */ |
126 | memset(to, 0, sa_size); | ||
127 | for (cmsgptr = CMSG_FIRSTHDR(&msg); | 134 | for (cmsgptr = CMSG_FIRSTHDR(&msg); |
128 | cmsgptr != NULL; | 135 | cmsgptr != NULL; |
129 | cmsgptr = CMSG_NXTHDR(&msg, cmsgptr) | 136 | cmsgptr = CMSG_NXTHDR(&msg, cmsgptr) |
@@ -138,9 +145,9 @@ recv_from_to(int fd, void *buf, size_t len, int flags, | |||
138 | #undef pktinfo | 145 | #undef pktinfo |
139 | break; | 146 | break; |
140 | } | 147 | } |
141 | #if ENABLE_FEATURE_IPV6 && defined(IP6_PKTINFO) | 148 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
142 | if (cmsgptr->cmsg_level == IPPROTO_IPV6 | 149 | if (cmsgptr->cmsg_level == IPPROTO_IPV6 |
143 | && cmsgptr->cmsg_type == IP6_PKTINFO | 150 | && cmsgptr->cmsg_type == IPV6_PKTINFO |
144 | ) { | 151 | ) { |
145 | #define pktinfo(cmsgptr) ( (struct in6_pktinfo*)(CMSG_DATA(cmsgptr)) ) | 152 | #define pktinfo(cmsgptr) ( (struct in6_pktinfo*)(CMSG_DATA(cmsgptr)) ) |
146 | to->sa_family = AF_INET6; | 153 | to->sa_family = AF_INET6; |