Example #1
0
static int send_udp_sendmmsg(int fd, char *data)
{
	const int max_nr_msg = ETH_MAX_MTU / ETH_DATA_LEN;
	struct mmsghdr mmsgs[max_nr_msg];
	struct iovec iov[max_nr_msg];
	unsigned int off = 0, left;
	int i = 0, ret;

	memset(mmsgs, 0, sizeof(mmsgs));

	left = cfg_payload_len;
	while (left) {
		if (i == max_nr_msg)
			error(1, 0, "sendmmsg: exceeds max_nr_msg");

		iov[i].iov_base = data + off;
		iov[i].iov_len = cfg_mss < left ? cfg_mss : left;

		mmsgs[i].msg_hdr.msg_iov = iov + i;
		mmsgs[i].msg_hdr.msg_iovlen = 1;

		off += iov[i].iov_len;
		left -= iov[i].iov_len;
		i++;
	}

	ret = sendmmsg(fd, mmsgs, i, cfg_zerocopy ? MSG_ZEROCOPY : 0);
	if (ret == -1)
		error(1, errno, "sendmmsg");

	return ret;
}
Example #2
0
int
udp_multisend_send( udp_multisend_t *um, int fd, int packets )
{
  static char use_emul = 0;
  int n, i;
  if (um == NULL) {
    errno = EINVAL;
    return -1;
  }
  if (packets > um->um_packets)
    packets = um->um_packets;
  for (i = 0; i < packets; i++)
    ((struct mmsghdr *)um->um_msg)[i].msg_len = um->um_iovec[i].iov_len;
  if (!use_emul) {
    n = sendmmsg(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT);
  } else {
    n = -1;
    errno = ENOSYS;
  }
  if (n < 0 && errno == ENOSYS) {
    use_emul = 1;
    n = sendmmsg_i(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT);
  }
  if (n > 0) {
    for (i = 0; i < n; i++)
      um->um_iovec[i].iov_len = ((struct mmsghdr *)um->um_msg)[i].msg_len;
  }
  return n;
}
Example #3
0
void send_message(struct client_state *state, int amount) {
    int r = sendmmsg(state->sock, state->out_msgs, amount, 0);
    if (r <= 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
        }
        if (errno == ECONNREFUSED) {
        }
        perror("sendmmsg()");
    }
    if (state->verbose) {
        printf("Send %d messages\n", r);
    }
}
Example #4
0
void thread_loop(void *userdata) {
	struct state *state = userdata;

	struct mmsghdr *messages = calloc(state->packets_in_buf, sizeof(struct mmsghdr));
	struct iovec *iovecs = calloc(state->packets_in_buf, sizeof(struct iovec));

	int fd = net_connect_udp(state->target_addr, state->src_port);

	int i;
	for (i = 0; i < state->packets_in_buf; i++) {
		struct iovec *iovec = &iovecs[i];
		struct mmsghdr *msg = &messages[i];

		msg->msg_hdr.msg_iov = iovec;
		msg->msg_hdr.msg_iovlen = 1;

		iovec->iov_base = (void*)state->payload;
		iovec->iov_len = state->payload_sz;
	}
	
	while (1) {
		int r = sendmmsg(fd, messages, state->packets_in_buf, 0);
		if (r <= 0) {
			if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
				continue;
			}

			if (errno == ECONNREFUSED) {
				continue;
			}
			PFATAL("sendmmsg()");
		}
		int i, bytes = 0;
		for (i = 0; i < r; i++) {
			struct mmsghdr *msg = &messages[i];
			/* char *buf = msg->msg_hdr.msg_iov->iov_base; */
			int len = msg->msg_len;
			msg->msg_hdr.msg_flags = 0;
			msg->msg_len = 0;
			bytes += len;
		}
	}
}
Example #5
0
static jint netty_epoll_native_sendmmsg0(JNIEnv* env, jclass clazz, jint fd, jobjectArray packets, jint offset, jint len) {
    struct mmsghdr msg[len];
    struct sockaddr_storage addr[len];
    socklen_t addrSize;
    int i;

    memset(msg, 0, sizeof(msg));

    for (i = 0; i < len; i++) {

        jobject packet = (*env)->GetObjectArrayElement(env, packets, i + offset);
        jbyteArray address = (jbyteArray) (*env)->GetObjectField(env, packet, packetAddrFieldId);
        jint scopeId = (*env)->GetIntField(env, packet, packetScopeIdFieldId);
        jint port = (*env)->GetIntField(env, packet, packetPortFieldId);

        if (netty_unix_socket_initSockaddr(env, address, scopeId, port, &addr[i], &addrSize) == -1) {
            return -1;
        }

        msg[i].msg_hdr.msg_name = &addr[i];
        msg[i].msg_hdr.msg_namelen = addrSize;

        msg[i].msg_hdr.msg_iov = (struct iovec*) (intptr_t) (*env)->GetLongField(env, packet, packetMemoryAddressFieldId);
        msg[i].msg_hdr.msg_iovlen = (*env)->GetIntField(env, packet, packetCountFieldId);;
    }

    ssize_t res;
    int err;
    do {
       res = sendmmsg(fd, msg, len, 0);
       // keep on writing if it was interrupted
    } while (res == -1 && ((err = errno) == EINTR));

    if (res < 0) {
        return -err;
    }
    return (jint) res;
}
Example #6
0
static void* writemsg(void* param)
{
	int sockfd;
	struct mmsghdr msg = {{ 0 }, 0 };
	struct sockaddr_in soaddr = { 0 };

	(void)param; /* UNUSED */
	soaddr.sin_family = AF_INET;
	soaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	soaddr.sin_port = htons(UDP_SERVER_PORT);
	
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd == -1)
	{
		perror("socket client failed");
		pthread_exit((void*)-1);
	}

	if (connect(sockfd, (struct sockaddr *)&soaddr, sizeof(soaddr)) == -1) 
	{
		perror("connect failed");
		pthread_exit((void*)-1);
	}

	msg.msg_hdr.msg_iov = sendiovs;
	msg.msg_hdr.msg_iovlen = IOVECS;
	msg.msg_hdr.msg_control = sendiovs;
	msg.msg_hdr.msg_controllen = (IOVECS * sizeof(struct iovec));

	while(!stop_send)
	{
		sendmmsg(sockfd, &msg, 1, 0);
	}

	close(sockfd);
	pthread_exit(NULL);
}
Example #7
0
int main(int argc, char* argv[]) {
  char token = '!';
  struct timeval ts;
  pthread_t reader;
  int sock;

  gettimeofday(&ts, NULL);

  socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds);
  sock = sockfds[0];

  pthread_mutex_lock(&lock);

  pthread_create(&reader, NULL, reader_thread, NULL);

  /* Make the reader thread wait on its pthread_mutex_lock() */
  atomic_puts("M: sleeping ...");
  usleep(500000);
  atomic_puts("M: unlocking mutex ...");
  pthread_mutex_unlock(&lock);
  atomic_puts("M:   ... done");

  /* Force a wait on read() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  test_assert(1 == write(sock, &token, sizeof(token)));
  ++token;
  atomic_puts("M:   ... done");
  /* Force a wait on readv() */
  {
    struct iovec v = { .iov_base = &token, .iov_len = sizeof(token) };

    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("r: writev('%c')'ing socket ...\n", token);
    test_assert(1 == writev(sock, &v, 1));
    ++token;
    atomic_puts("M:   ... done");
  }
  /* Force a wait on recv() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on recvfrom() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on recvfrom(&sock) */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: sending '%c' to socket ...\n", token);
  send(sock, &token, sizeof(token), 0);
  ++token;
  atomic_puts("M:   ... done");
  {
    struct mmsghdr mmsg = { { 0 } };
    struct iovec data = { 0 };
    int magic = msg_magic;

    data.iov_base = &magic;
    data.iov_len = sizeof(magic);
    mmsg.msg_hdr.msg_iov = &data;
    mmsg.msg_hdr.msg_iovlen = 1;

    struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CTRLMSG_LEN); // send a fd
    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type = SCM_RIGHTS;
    cmptr->cmsg_len = CTRLMSG_LEN;
    mmsg.msg_hdr.msg_control = cmptr;
    mmsg.msg_hdr.msg_controllen = CTRLMSG_LEN;
    *(int*)CMSG_DATA(cmptr) = STDERR_FILENO; // send stderr as fd

    /* Force a wait on recvmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmsg'ing 0x%x to socket ...\n", msg_magic);
    sendmsg(sock, &mmsg.msg_hdr, 0);
    atomic_puts("M:   ... done");

    /* Force a wait on recvmmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmmsg'ing 0x%x to socket ...\n", msg_magic);

    breakpoint();

    sendmmsg(sock, &mmsg, 1, 0);
    atomic_printf("M:   ... sent %u bytes\n", mmsg.msg_len);

    /* Force a wait on recvmmsg() */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: sendmmsg'ing(by socketcall) 0x%x to socket ...\n",
                  msg_magic);

#if defined(SYS_socketcall)
    struct sendmmsg_arg arg = { 0 };
    arg.sockfd = sock;
    arg.msgvec = &mmsg;
    arg.vlen = 1;
    syscall(SYS_socketcall, SYS_SENDMMSG, (void*)&arg);
#elif defined(SYS_sendmmsg)
    syscall(SYS_sendmmsg, sock, &mmsg, 1, 0);
#else
#error unable to call sendmmsg
#endif

    free(cmptr);
  }
  {
    struct msghdr msg = { 0 };
    struct iovec iovs[2];
    char c1 = token++;
    char c2 = token++;

    iovs[0].iov_base = &c1;
    iovs[0].iov_len = sizeof(c1);
    iovs[1].iov_base = &c2;
    iovs[1].iov_len = sizeof(c2);

    msg.msg_iov = iovs;
    msg.msg_iovlen = sizeof(iovs) / sizeof(iovs[0]);

    /* Force a wait on recvmsg(). */
    atomic_puts("M: sleeping again ...");
    usleep(500000);
    atomic_printf("M: writing { '%c', '%c' } to socket ...\n", c1, c2);
    test_assert(2 == sendmsg(sock, &msg, 0));
    atomic_puts("M:   ... done");
  }
  /* Force a wait on poll() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on ppoll() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on select(), raw syscall */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on select(), library call */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on epoll_wait() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  ++token;
  atomic_puts("M:   ... done");

  /* Force a wait on write() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: reading socket ...\n");
  ++token;
  {
    char* buf = (char*)malloc(num_sockbuf_bytes);
    int i;
    for (i = 0; i < 2; ++i) {
      read_all_chunks(sock, buf, num_sockbuf_bytes, token);
      ++token;
    }
    free(buf);
  }
  atomic_puts("M:   ... done");

  /* Force a wait on read() */
  atomic_puts("M: sleeping again ...");
  usleep(500000);
  atomic_printf("M: writing '%c' to socket ...\n", token);
  write(sock, &token, sizeof(token));
  atomic_puts("M:   ... done");

  pthread_join(reader, NULL);

  atomic_puts("EXIT-SUCCESS");
  return 0;
}
Example #8
0
File: block.c Project: KurSh/rr
int main(int argc, char *argv[]) {
	char token = '!';
	struct timeval ts;
	pthread_t reader;
	int sock;

	gettimeofday(&ts, NULL);

	socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds);
	sock = sockfds[0];

	pthread_barrier_init(&cheater_barrier, NULL, 2);

	pthread_mutex_lock(&lock);

	pthread_create(&reader, NULL, reader_thread, NULL);

	/* Make the reader thread wait on its pthread_mutex_lock() */
	atomic_puts("M: sleeping ...");
	usleep(500000);
	atomic_puts("M: unlocking mutex ...");
	pthread_mutex_unlock(&lock);
	atomic_puts("M:   ... done");

	/* Force a wait on read() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	test_assert(1 == write(sock, &token, sizeof(token)));
	++token;
	atomic_puts("M:   ... done");
	/* Force a wait on readv() */
	{
		struct iovec v = { .iov_base = &token,
				   .iov_len = sizeof(token) };

		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("r: writev('%c')'ing socket ...\n", token);
		test_assert(1 == writev(sock, &v, 1));
		++token;
		atomic_puts("M:   ... done");
	}
	/* Force a wait on recv() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on recvfrom() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on recvfrom(&sock) */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: sending '%c' to socket ...\n", token);
	send(sock, &token, sizeof(token), 0);
	++token;
	atomic_puts("M:   ... done");
	{
		struct mmsghdr mmsg = {{ 0 }};
		struct iovec data = { 0 };
		int magic = msg_magic;

		data.iov_base = &magic;
		data.iov_len = sizeof(magic);
		mmsg.msg_hdr.msg_iov = &data;
		mmsg.msg_hdr.msg_iovlen = 1;

		/* Force a wait on recvmsg() */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: sendmsg'ing 0x%x to socket ...\n",
			      msg_magic);
		sendmsg(sock, &mmsg.msg_hdr, 0);
		atomic_puts("M:   ... done");

		/* Force a wait on recvmmsg() */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: sendmmsg'ing 0x%x to socket ...\n",
			      msg_magic);

		breakpoint();

		sendmmsg(sock, &mmsg, 1, 0);
		atomic_printf("M:   ... sent %u bytes\n", mmsg.msg_len);
		pthread_barrier_wait(&cheater_barrier);
	}
	{
		struct msghdr msg = { 0 };
		struct iovec iovs[2];
		char c1 = token++;
		char c2 = token++;

		iovs[0].iov_base = &c1;
		iovs[0].iov_len = sizeof(c1);
		iovs[1].iov_base = &c2;
		iovs[1].iov_len = sizeof(c2);

		msg.msg_iov = iovs;
		msg.msg_iovlen = sizeof(iovs) / sizeof(iovs[0]);

		/* Force a wait on recvmsg(). */
		atomic_puts("M: sleeping again ...");
		usleep(500000);
		atomic_printf("M: writing { '%c', '%c' } to socket ...\n",
			      c1, c2);
		test_assert(2 == sendmsg(sock, &msg, 0));
		atomic_puts("M:   ... done");
	}
	/* Force a wait on poll() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on ppoll() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on select() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on epoll_wait() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	++token;
	atomic_puts("M:   ... done");

	/* Force a wait on write() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: reading socket ...\n");
	++token;
	{
		char* buf = (char*)malloc(num_sockbuf_bytes);
		int i;
		for (i = 0; i < 2; ++i) {
			read_all_chunks(sock, buf, num_sockbuf_bytes, token);
			++token;
		}
		free(buf);
	}
	atomic_puts("M:   ... done");

	/* Force a wait on read() */
	atomic_puts("M: sleeping again ...");
	usleep(500000);
	atomic_printf("M: writing '%c' to socket ...\n", token);
	write(sock, &token, sizeof(token));
	atomic_puts("M:   ... done");

	pthread_join(reader, NULL);

	atomic_puts("EXIT-SUCCESS");
	return 0;
}
Example #9
0
int main(int argc, char* argv[])
{
signal( SIGTRAP, SIG_IGN );
params p = get_params( argc, argv );
unistd::addrinfo hint = addrinfo{ 0, AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0, nullptr, nullptr, nullptr };
std::vector<unistd::addrinfo> addrs = unistd::getaddrinfo( p.hostname, p.port, hint );
const unistd::addrinfo& addr = addrs.at( 0 );
unistd::fd sock = unistd::socket( addr );
subscribe_events( sock );

if ( 0 != p.sndbuf )
    unistd::setsockopt( sock, SOL_SOCKET, SO_SNDBUF, p.sndbuf );

if ( 0 != p.mtu )
    {
    unistd::setsockopt( sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, IP_PMTUDISC_DONT );
    unistd::setsockopt( sock, IPPROTO_IPV6, IPV6_MTU, p.mtu );
    }

if ( p.nodelay )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_NODELAY, 1 );

if ( 0 != p.max_burst )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_MAX_BURST, p.max_burst );

if ( 0 != p.maxseg )
    unistd::setsockopt( sock, SOL_SCTP, SCTP_MAXSEG, p.maxseg );

int sndbuf = 0;
socklen_t len = sizeof(sndbuf);
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len );
fprintf( stderr, "sndbuf: set=%d get=%d\n", p.sndbuf, sndbuf );

if ( 0 != p.rcvbuf )
    unistd::setsockopt( sock, SOL_SOCKET, SO_RCVBUF, p.rcvbuf );

sctp_initmsg init_params;
memset( &init_params, 0, sizeof(init_params) );
init_params.sinit_num_ostreams = 1;
init_params.sinit_max_instreams = 1;
init_params.sinit_max_attempts = 3;
init_params.sinit_max_init_timeo = 100;
unistd::setsockopt( sock, SOL_SCTP, SCTP_INITMSG, init_params );

unistd::connect( sock, addr );

sctp_assoc_t assoc_id = 0;
while ( assoc_id == 0 )
    {
    std::vector<char> cmsg_buff( CMSG_SPACE( sizeof( sctp_sndrcvinfo ) ) );
    std::vector<char> msg_buff( 8192 ); //TODO:

    struct iovec iov;
    memset( &iov, 0, sizeof(iov) );
    iov.iov_base = msg_buff.data();
    iov.iov_len = msg_buff.size();

    struct msghdr hdr;
    memset( &hdr, 0, sizeof(hdr) );
    hdr.msg_name = nullptr;
    hdr.msg_namelen = 0;
    hdr.msg_iov = &iov;
    hdr.msg_iovlen = 1;
    hdr.msg_control = cmsg_buff.data();
    hdr.msg_controllen = cmsg_buff.size();
    hdr.msg_flags = 0;

    ssize_t nrecv = 0;
    TEMP_FAILURE_RETRY( nrecv = recvmsg( sock, &hdr, 0 ) );
    if ( 0 == nrecv )
        raise( SIGTRAP );
    if ( -1 == nrecv )
        raise( SIGTRAP );
    if ( hdr.msg_flags & MSG_NOTIFICATION )
        {
        const sctp_notification& notify = *reinterpret_cast<const sctp_notification*>( hdr.msg_iov[0].iov_base );
        switch ( notify.sn_header.sn_type )
            {
            case SCTP_ASSOC_CHANGE:
                {
                const auto& sac = notify.sn_assoc_change;
        std::cout << " assoc_id=" << sac.sac_assoc_id << " error=" << sac.sac_error << " in=" << sac.sac_inbound_streams << " out=" << sac.sac_outbound_streams << std::endl;
                assoc_id = sac.sac_assoc_id;
                break;
                }
            case SCTP_REMOTE_ERROR:
                {
                const auto& sre = notify.sn_remote_error;
                printf( "^^^ remote_error: err=%hu len=%hu\n", ntohs(sre.sre_error), ntohs(sre.sre_length) );
                return EXIT_FAILURE;
                }
            case SCTP_SHUTDOWN_EVENT:
                {
                printf( "^^^ SCTP_SHUTDOWN_EVENT\n" );
                return EXIT_FAILURE;
                }
            }
        }
    }

//int flags = fcntl( sock, F_GETFL, 0 );
//fcntl( sock, F_SETFL, flags | O_NONBLOCK );

const std::vector<char> msg = generate_message( p.msgsize );
struct iovec iov;
iov.iov_base = const_cast<char*>( msg.data() );
iov.iov_len = msg.size();
std::vector<char> cmsg_buff( CMSG_SPACE( sizeof( sctp_sndrcvinfo ) ) );

struct mmsghdr mhdr;
memset( &mhdr, 0, sizeof(mhdr) );
struct msghdr& hdr = mhdr.msg_hdr;
hdr.msg_name = nullptr;
hdr.msg_namelen = 0;
hdr.msg_iov = &iov;
hdr.msg_iovlen = 1;
hdr.msg_flags = 0;
hdr.msg_control = cmsg_buff.data();
hdr.msg_controllen = cmsg_buff.size();

cmsghdr* cmsg = CMSG_FIRSTHDR( &hdr );
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN( sizeof( sctp_sndrcvinfo ) );
sctp_sndrcvinfo& cmsg_data = *reinterpret_cast<sctp_sndrcvinfo*>( CMSG_DATA( cmsg ) );
cmsg_data.sinfo_stream = 0;
cmsg_data.sinfo_ssn = 0; //ignored
cmsg_data.sinfo_flags = SCTP_UNORDERED;
cmsg_data.sinfo_ppid = 31337;
cmsg_data.sinfo_context = 123456;
cmsg_data.sinfo_timetolive = 0;
cmsg_data.sinfo_tsn = 0; //ignored
cmsg_data.sinfo_cumtsn = 0; //ignored
cmsg_data.sinfo_assoc_id = assoc_id;

std::vector<mmsghdr> mhdrs( p.batch, mhdr );

while ( p.count )
    {
    const ssize_t count = std::min<uint64_t>( p.batch, p.count );
    ssize_t nsend = 0;
    TEMP_FAILURE_RETRY( nsend = sendmmsg( sock, mhdrs.data(), count, 0 ) );
    if ( 0 == nsend )
        raise( SIGTRAP );
    if ( -1 == nsend )
        raise( SIGTRAP );
    if ( count != nsend )
        raise( SIGTRAP );
    p.count -= count;
    }

//raise( SIGTRAP );

sock.close();
return EXIT_SUCCESS;
}
Example #10
0
int main()
{
    /* Only try this test if we have sendmmsg(). Unfortunately,
     * on RHEL6 we have SYS_sendmmsg(), but no glibc support for
     * sendmmsg(). */
#if defined(SYS_sendmmsg) || defined (SYS_SENDMMSG)
    int s, fd_null;
    struct sockaddr_in sin1, from;
    pid_t pid = 0;
    char buf[2][1024];
    fd_set rdfds;
    struct mmsghdr msgs[2];
    struct iovec iov[2];
    socklen_t fromlen;

    /* initialize sockaddr's */
    sin1.sin_family = AF_INET;
    sin1.sin_port = htons((getpid() % 32768) + 11000);
    sin1.sin_addr.s_addr = INADDR_ANY;

    pid = start_server(&sin1);

    fromlen = sizeof(from);

    memset(msgs, 0, sizeof(msgs));
    iov[0].iov_base = buf[0];
    iov[0].iov_len = sizeof(buf[0]);
    msgs[0].msg_hdr.msg_iov = &iov[0];
    msgs[0].msg_hdr.msg_iovlen = 1;
    iov[1].iov_base = buf[1];
    iov[1].iov_len = sizeof(buf[1]);
    msgs[1].msg_hdr.msg_iov = &iov[1];
    msgs[1].msg_hdr.msg_iovlen = 1;

    fd_null = open("/dev/null", O_WRONLY);

    sendmmsg(-1, msgs, 2, 0);
    //staptest// sendmmsg (-1, XXXX, 2, 0x0) = -NNNN (EBADF)

    sendmmsg(fd_null, msgs, 2, MSG_DONTWAIT);
    //staptest// sendmmsg (NNNN, XXXX, 2, MSG_DONTWAIT) = -NNNN (ENOTSOCK)

    s = socket(PF_INET, SOCK_DGRAM, 0);
    //staptest// socket (PF_INET, SOCK_DGRAM, IPPROTO_IP) = NNNN

    sendmmsg(s, msgs, 2, 0);
    //staptest// sendmmsg (NNNN, XXXX, 2, 0x0) = -NNNN (EDESTADDRREQ)

    sendmmsg(s, (struct mmsghdr *)-1, 2, 0);
    //staptest// sendmmsg (NNNN, 0x[f]+, 2, 0x0) = -NNNN (EFAULT)

    close(s);
    //staptest// close (NNNN) = 0

    s = socket(PF_INET, SOCK_STREAM, 0);
    //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN

    connect(s, (struct sockaddr *)&sin1, sizeof(sin1));
    //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0

    // Note that the exact failure return value can differ here, so
    // we'll just ignore it.
    sendmmsg(s, msgs, 2, -1);
    //staptest// sendmmsg (NNNN, XXXX, 2, MSG_[^ ]+|XXXX) = -NNNN

    close(s);
    //staptest// close (NNNN) = 0

    s = socket(PF_INET, SOCK_STREAM, 0);
    //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN

    connect(s, (struct sockaddr *)&sin1, sizeof(sin1));
    //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0

    // We don't want to wait for -1 vectors, since we'd be waiting for
    // a long time...
    sendmmsg(s, msgs, -1, MSG_DONTWAIT);
    //staptest// sendmmsg (NNNN, XXXX, 4294967295, MSG_DONTWAIT)

    close(s);
    //staptest// close (NNNN) = 0

    s = socket(PF_INET, SOCK_STREAM, 0);
    //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN

    connect(s, (struct sockaddr *)&sin1, sizeof(sin1));
    //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0

    sendmmsg(s, msgs, 2, MSG_DONTWAIT);
    //staptest// sendmmsg (NNNN, XXXX, 2, MSG_DONTWAIT) = NNNN

    close(s);
    //staptest// close (NNNN) = 0

    close(fd_null);
    //staptest// close (NNNN) = 0

    if (pid > 0)
	(void)kill(pid, SIGKILL);	/* kill server */
    //staptest// kill (NNNN, SIGKILL) = 0
#endif

    return 0;
}
/*
 *  stress_socket_server()
 *	server writer
 */
static int stress_socket_server(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name,
	const pid_t pid,
	const pid_t ppid)
{
	char buf[SOCKET_BUF];
	int fd, status;
	int so_reuseaddr = 1;
	socklen_t addr_len = 0;
	struct sockaddr *addr;
	uint64_t msgs = 0;
	int rc = EXIT_SUCCESS;

	setpgid(pid, pgrp);

	if (stress_sighandler(name, SIGALRM, handle_socket_sigalrm, NULL) < 0) {
		rc = EXIT_FAILURE;
		goto die;
	}
	if ((fd = socket(opt_socket_domain, SOCK_STREAM, 0)) < 0) {
		rc = exit_status(errno);
		pr_fail_dbg(name, "socket");
		goto die;
	}
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
		&so_reuseaddr, sizeof(so_reuseaddr)) < 0) {
		pr_fail_dbg(name, "setsockopt");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	stress_set_sockaddr(name, instance, ppid,
		opt_socket_domain, opt_socket_port, &addr, &addr_len);
	if (bind(fd, addr, addr_len) < 0) {
		rc = exit_status(errno);
		pr_fail_dbg(name, "bind");
		goto die_close;
	}
	if (listen(fd, 10) < 0) {
		pr_fail_dbg(name, "listen");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	do {
		int sfd = accept(fd, (struct sockaddr *)NULL, NULL);
		if (sfd >= 0) {
			size_t i, j;
			struct sockaddr addr;
			socklen_t len;
			int sndbuf;
			struct msghdr msg;
			struct iovec vec[sizeof(buf)/16];
#if defined(HAVE_SENDMMSG)
			struct mmsghdr msgvec[MSGVEC_SIZE];
			unsigned int msg_len = 0;
#endif
#if defined(SOCKET_NODELAY)
			int one = 1;
#endif

			len = sizeof(addr);
			if (getsockname(fd, &addr, &len) < 0) {
				pr_fail_dbg(name, "getsockname");
				(void)close(sfd);
				break;
			}
			len = sizeof(sndbuf);
			if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) < 0) {
				pr_fail_dbg(name, "getsockopt");
				(void)close(sfd);
				break;
			}
#if defined(SOCKET_NODELAY)
			if (opt_flags & OPT_FLAGS_SOCKET_NODELAY) {
				if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) {
					pr_inf(stderr, "%s: setsockopt TCP_NODELAY "
						"failed and disabled, errno=%d (%s)\n",
						name, errno, strerror(errno));
					opt_flags &= ~OPT_FLAGS_SOCKET_NODELAY;
				}
			}
#endif
			memset(buf, 'A' + (*counter % 26), sizeof(buf));
			switch (opt_socket_opts) {
			case SOCKET_OPT_SEND:
				for (i = 16; i < sizeof(buf); i += 16) {
					ssize_t ret = send(sfd, buf, i, 0);
					if (ret < 0) {
						if (errno != EINTR)
							pr_fail_dbg(name, "send");
						break;
					} else
						msgs++;
				}
				break;
			case SOCKET_OPT_SENDMSG:
				for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) {
					vec[j].iov_base = buf;
					vec[j].iov_len = i;
				}
				memset(&msg, 0, sizeof(msg));
				msg.msg_iov = vec;
				msg.msg_iovlen = j;
				if (sendmsg(sfd, &msg, 0) < 0) {
					if (errno != EINTR)
						pr_fail_dbg(name, "sendmsg");
				} else
					msgs += j;
				break;
#if defined(HAVE_SENDMMSG)
			case SOCKET_OPT_SENDMMSG:
				memset(msgvec, 0, sizeof(msgvec));
				for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) {
					vec[j].iov_base = buf;
					vec[j].iov_len = i;
					msg_len += i;
				}
				for (i = 0; i < MSGVEC_SIZE; i++) {
					msgvec[i].msg_hdr.msg_iov = vec;
					msgvec[i].msg_hdr.msg_iovlen = j;
				}
				if (sendmmsg(sfd, msgvec, MSGVEC_SIZE, 0) < 0) {
					if (errno != EINTR)
						pr_fail_dbg(name, "sendmmsg");
				} else
					msgs += (MSGVEC_SIZE * j);
				break;
#endif
			default:
				/* Should never happen */
				pr_err(stderr, "%s: bad option %d\n", name, opt_socket_opts);
				(void)close(sfd);
				goto die_close;
			}
			if (getpeername(sfd, &addr, &len) < 0) {
				pr_fail_dbg(name, "getpeername");
			}
			(void)close(sfd);
		}
		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

die_close:
	(void)close(fd);
die:
#ifdef AF_UNIX
	if (opt_socket_domain == AF_UNIX) {
		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
		(void)unlink(addr_un->sun_path);
	}
#endif
	if (pid) {
		(void)kill(pid, SIGKILL);
		(void)waitpid(pid, &status, 0);
	}
	pr_dbg(stderr, "%s: %" PRIu64 " messages sent\n", name, msgs);

	return rc;
}
Example #12
0
int aeron_udp_channel_transport_recvmmsg(
    aeron_udp_channel_transport_t *transport,
    struct mmsghdr *msgvec,
    size_t vlen,
    aeron_udp_transport_recv_func_t recv_func,
    void *clientd)
{
#if defined(HAVE_RECVMMSG)
    struct timespec tv = {.tv_nsec = 0, .tv_sec = 0};

    int result = recvmmsg(transport->fd, msgvec, vlen, 0, &tv);
    if (result < 0)
    {
        int err = errno;

        if (EINTR == err || EAGAIN == err)
        {
            return 0;
        }

        aeron_set_err(err, "recvmmsg: %s", strerror(err));
        return -1;
    }
    else if (0 == result)
    {
        return 0;
    }
    else
    {
        for (size_t i = 0, length = result; i < length; i++)
        {
            recv_func(
                clientd,
                transport->dispatch_clientd,
                msgvec[i].msg_hdr.msg_iov[0].iov_base,
                msgvec[i].msg_len,
                msgvec[i].msg_hdr.msg_name);
        }

        return result;
    }
#else
    int work_count = 0;

    for (size_t i = 0, length = vlen; i < length; i++)
    {
        ssize_t result = recvmsg(transport->fd, &msgvec[i].msg_hdr, 0);

        if (result < 0)
        {
            int err = errno;

            if (EINTR == err || EAGAIN == err)
            {
                break;
            }

            aeron_set_err(err, "recvmsg: %s", strerror(err));
            return -1;
        }
        if (0 == result)
        {
            break;
        }

        msgvec[i].msg_len = (unsigned int)result;
        recv_func(
            clientd,
            transport->dispatch_clientd,
            msgvec[i].msg_hdr.msg_iov[0].iov_base,
            msgvec[i].msg_len,
            msgvec[i].msg_hdr.msg_name);
        work_count++;
    }

    return work_count;
#endif
}

int aeron_udp_channel_transport_sendmmsg(
    aeron_udp_channel_transport_t *transport,
    struct mmsghdr *msgvec,
    size_t vlen)
{
#if defined(HAVE_RECVMMSG)
    int sendmmsg_result = sendmmsg(transport->fd, msgvec, vlen, 0);
    if (sendmmsg_result < 0)
    {
        aeron_set_err(errno, "sendmmsg: %s", strerror(errno));
        return -1;
    }

    return sendmmsg_result;
#else
    int result = 0;

    for (size_t i = 0, length = vlen; i < length; i++)
    {
        ssize_t sendmsg_result = sendmsg(transport->fd, &msgvec[i].msg_hdr, 0);
        if (sendmsg_result < 0)
        {
            aeron_set_err(errno, "sendmsg: %s", strerror(errno));
            return -1;
        }

        msgvec[i].msg_len = (unsigned int)sendmsg_result;

        if (0 == sendmsg_result)
        {
            break;
        }

        result++;
    }

    return result;
#endif
}
Example #13
0
int CNIOLinux_sendmmsg(int sockfd, CNIOLinux_mmsghdr *msgvec, unsigned int vlen, int flags) {
    // This is technically undefined behaviour, but it's basically fine because these types are the same size, and we
    // don't think the compiler is inclined to blow anything up here.
    return sendmmsg(sockfd, (struct mmsghdr *)msgvec, vlen, flags);
}