Created
August 1, 2018 16:05
-
-
Save alexandre-janniaux/db34e6bb20c97656ca61e55bc15faf71 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <linux/memfd.h> | |
#include <sys/mman.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <string.h> | |
void broadcaster( int socket ) | |
{ | |
unsigned counter = 0; | |
for( ;; ) | |
{ | |
int fd = memfd_create( "test_fd", MFD_CLOEXEC ); | |
char buffer[512]; | |
struct iovec iov = | |
{ | |
.iov_base = &counter, | |
.iov_len = sizeof( counter ) | |
}; | |
struct msghdr hdr = | |
{ | |
.msg_name = NULL, | |
.msg_namelen = 0, | |
.msg_iov = &iov, | |
.msg_iovlen = 1, | |
.msg_control = buffer, | |
.msg_controllen = sizeof( buffer ) | |
}; | |
struct cmsghdr *cmsg = CMSG_FIRSTHDR( &hdr ); | |
cmsg->cmsg_level = SOL_SOCKET; | |
cmsg->cmsg_type = SCM_RIGHTS; | |
cmsg->cmsg_len = CMSG_LEN( sizeof( int ) ); | |
void *p_data = CMSG_DATA( cmsg ); | |
memcpy( p_data, &fd, sizeof( int ) ); | |
hdr.msg_controllen = cmsg->cmsg_len; | |
ssize_t size = sendmsg( socket, &hdr, MSG_EOR ); | |
printf( "[BROADCAST] sent %dth file descriptor, which was %d\n", | |
counter, fd ); | |
close( fd ); | |
counter ++; | |
} | |
} | |
void receiver( int socket ) | |
{ | |
unsigned counter = 0; | |
unsigned packet_counter = 0; | |
for( ;; ) | |
{ | |
char buffer[512]; | |
struct iovec iov = | |
{ | |
.iov_base = &counter, | |
.iov_len = sizeof( counter ) | |
}; | |
struct msghdr hdr = | |
{ | |
.msg_name = NULL, | |
.msg_namelen = 0, | |
.msg_iov = &iov, | |
.msg_iovlen = 1, | |
.msg_control = buffer, | |
.msg_controllen = sizeof( buffer ) | |
}; | |
ssize_t size = recvmsg(socket, &hdr, 0); | |
if( hdr.msg_flags & MSG_CTRUNC ) | |
{ | |
printf( "[RECEIVER] got MSG_CTRUNC at %dth packet\n", | |
packet_counter ); | |
} | |
struct cmsghdr *cmsg = CMSG_FIRSTHDR( &hdr ); | |
while( cmsg != NULL ) | |
{ | |
if( cmsg->cmsg_level == SOL_SOCKET | |
&& cmsg->cmsg_type == SCM_RIGHTS ) | |
{ | |
int fd; | |
memcpy( &fd, CMSG_DATA( cmsg ), | |
sizeof( int ) ); | |
printf( "[RECEIVER] received fd in %dth packet, " | |
"marked %dth, with value %d\n", | |
packet_counter, counter, fd ); | |
} | |
cmsg = CMSG_NXTHDR( &hdr, cmsg ); | |
} | |
packet_counter ++; | |
} | |
} | |
int main( int argc, char** argv ) | |
{ | |
int sockets[2]; | |
{ | |
int ret = socketpair( AF_UNIX, SOCK_SEQPACKET, 0, sockets); | |
if( ret != 0 ) | |
return -1; | |
} | |
{ | |
int ret = fork(); | |
if( ret > 0 ) | |
receiver(sockets[0]); | |
else if( ret == 0 ) | |
broadcaster(sockets[1]); | |
else | |
return -1; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment