summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2014-05-14 11:28:33 +0200
committerMichael Adam <obnox@samba.org>2014-05-22 12:05:37 +0200
commitb02ecdf338ce6bcefaa91ec0a8fe3dce5b8925a8 (patch)
treeb1960779c06bffb9a0fa907c0d8abd7f9552a59e
parent6f96c9df7cdc2e4b80bad9cd782a9256e1f03625 (diff)
downloadsocket_wrapper-b02ecdf338ce6bcefaa91ec0a8fe3dce5b8925a8.tar.gz
socket_wrapper-b02ecdf338ce6bcefaa91ec0a8fe3dce5b8925a8.tar.xz
socket_wrapper-b02ecdf338ce6bcefaa91ec0a8fe3dce5b8925a8.zip
tests: Add support to sending IP_PKTINFO in echo_srv.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Michael Adam <obnox@samba.org>
-rw-r--r--tests/echo_srv.c91
1 files changed, 88 insertions, 3 deletions
diff --git a/tests/echo_srv.c b/tests/echo_srv.c
index d571857..33f2ebd 100644
--- a/tests/echo_srv.c
+++ b/tests/echo_srv.c
@@ -32,7 +32,7 @@
#define BACKLOG 5
#ifndef BUFSIZE
-#define BUFSIZE 4194304
+#define BUFSIZE 0x400000
#endif /* BUFSIZE */
#ifndef discard_const
@@ -635,6 +635,89 @@ static ssize_t echo_udp_recv_from_to(int sock,
return ret;
}
+static ssize_t echo_udp_send_to_from(int sock,
+ void *buf, size_t buflen, int flags,
+ struct sockaddr *to, socklen_t tolen,
+ struct sockaddr *from, socklen_t fromlen)
+{
+ struct msghdr msg;
+ struct iovec iov;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ size_t clen = CMSG_SPACE(sizeof(union pktinfo));
+ char cbuf[clen];
+ struct cmsghdr *cmsgptr;
+#endif
+ ssize_t ret;
+
+ iov.iov_base = buf;
+ iov.iov_len = buflen;
+
+ ZERO_STRUCT(msg);
+
+ msg.msg_name = to;
+ msg.msg_namelen = tolen;
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ memset(cbuf, 0, clen);
+
+ msg.msg_control = cbuf;
+ msg.msg_controllen = clen;
+
+ cmsgptr = CMSG_FIRSTHDR(&msg);
+ msg.msg_controllen = 0;
+
+ switch (from->sa_family) {
+ case AF_INET: {
+ struct in_pktinfo *p = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
+ const struct sockaddr_in *from4 = (const struct sockaddr_in *)from;
+
+ if (fromlen != sizeof(struct sockaddr_in)) {
+ break;
+ }
+
+ cmsgptr->cmsg_level = IPPROTO_IP;
+ cmsgptr->cmsg_type = IP_PKTINFO;
+ cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+ p->ipi_spec_dst = from4->sin_addr;
+
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
+
+ break;
+ }
+#ifdef IPV6_PKTINFO
+ case AF_INET6: {
+ struct in6_pktinfo *p = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
+ const struct sockaddr_in6 *from6 = (const struct sockaddr_in6 *)from;
+
+ if (fromlen != sizeof(struct sockaddr_in6)) {
+ break;
+ }
+
+ cmsgptr->cmsg_level = IPPROTO_IPV6;
+ cmsgptr->cmsg_type = IPV6_PKTINFO;
+ cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+
+ p->ipi6_addr = from6->sin6_addr;
+
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
+
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+#endif
+
+ ret = sendmsg(sock, &msg, flags);
+
+ return ret;
+}
+
static void echo_udp(int sock)
{
struct sockaddr_storage saddr;
@@ -654,8 +737,10 @@ static void echo_udp(int sock)
continue;
}
- bret = sendto(sock, buf, bret, 0,
- (struct sockaddr *) &saddr, saddrlen);
+ bret = echo_udp_send_to_from(sock,
+ buf, bret, 0,
+ (struct sockaddr *)&saddr, saddrlen,
+ (struct sockaddr *)&daddr, daddrlen);
if (bret == -1) {
perror("sendto");
continue;