Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3152511
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/poc-code/sctp-defrag-bug/common.c b/poc-code/sctp-defrag-bug/common.c
index 905f351a..1d840f3c 100644
--- a/poc-code/sctp-defrag-bug/common.c
+++ b/poc-code/sctp-defrag-bug/common.c
@@ -1,312 +1,328 @@
#include "config.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifdef HAVE_NETINET_SCTP_H
#include <netinet/sctp.h>
#include "common.h"
int strtoaddr(const char *host, const char *port, struct sockaddr_storage *ss, socklen_t sslen)
{
int err;
struct addrinfo hints;
struct addrinfo *result = NULL;
if (!host) {
errno = EINVAL;
return -1;
}
if (!port) {
errno = EINVAL;
return -1;
}
if (!ss) {
errno = EINVAL;
return -1;
}
if (!sslen) {
errno = EINVAL;
return -1;
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
err = getaddrinfo(host, port, &hints, &result);
if (!err) {
memmove(ss, result->ai_addr,
(sslen < result->ai_addrlen) ? sslen : result->ai_addrlen);
freeaddrinfo(result);
}
return err;
}
int _fdset_cloexec(int fd)
{
int fdflags;
fdflags = fcntl(fd, F_GETFD, 0);
if (fdflags < 0)
return -1;
fdflags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, fdflags) < 0)
return -1;
return 0;
}
int _fdset_nonblock(int fd)
{
int fdflags;
fdflags = fcntl(fd, F_GETFL, 0);
if (fdflags < 0)
return -1;
fdflags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, fdflags) < 0)
return -1;
return 0;
}
int setup_sctp_common_sock_opts(int sock, struct sockaddr_storage *ss)
{
struct sctp_event_subscribe events;
int value;
if (_fdset_cloexec(sock)) {
fprintf(stderr, "unable to set CLOEXEC socket opts (%d): %s\n",
errno, strerror(errno));
return -1;
}
if (_fdset_nonblock(sock)) {
fprintf(stderr, "unable to set NONBLOCK socket opts (%d): %s\n",
errno, strerror(errno));
return -1;
}
value = 8388608;
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set receive buffer (%d): %s\n",
errno, strerror(errno));
return -1;
}
value = 8388608;
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set send buffer (%d): %s\n",
errno, strerror(errno));
return -1;
}
if (ss->ss_family == AF_INET6) {
value = IPV6_PMTUDISC_PROBE;
if (setsockopt(sock, SOL_IPV6, IPV6_MTU_DISCOVER, &value, sizeof(value)) <0) {
fprintf(stderr, "Unable to set PMTUDISC (%d): %s\n",
errno, strerror(errno));
return -1;
}
} else {
value = IP_PMTUDISC_PROBE;
if (setsockopt(sock, SOL_IP, IP_MTU_DISCOVER, &value, sizeof(value)) <0) {
fprintf(stderr, "Unable to set PMTUDISC (%d): %s\n",
errno, strerror(errno));
return -1;
}
}
value = 1;
if (setsockopt(sock, SOL_SCTP, SCTP_NODELAY, &value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set SCTP_NODELAY (%d): %s\n",
errno, strerror(errno));
return -1;
}
#if 0 /* workaround */
value = 1;
if (setsockopt(sock, SOL_SCTP, SCTP_DISABLE_FRAGMENTS, &value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set SCTP_DISABLE_FRAGMENTS (%d): %s\n",
errno, strerror(errno));
return -1;
}
#endif
memset(&events, 0, sizeof (events));
events.sctp_data_io_event = 1;
events.sctp_association_event = 1;
events.sctp_send_failure_event = 1;
events.sctp_address_event = 1;
events.sctp_peer_error_event = 1;
events.sctp_shutdown_event = 1;
if (setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof (events)) < 0) {
fprintf(stderr, "Unable to configure SCTP notifications (%d): %s\n",
errno, strerror(errno));
return -1;
}
return 0;
}
int setup_sctp_server_sock_opts(int sock, struct sockaddr_storage *ss)
{
int value;
if (setup_sctp_common_sock_opts(sock, ss) < 0) {
return -1;
}
value = 1;
if (setsockopt(sock, SOL_IP, IP_FREEBIND, &value, sizeof(value)) <0) {
fprintf(stderr, "Unable to set FREEBIND (%d): %s\n",
errno, strerror(errno));
return -1;
}
if (ss->ss_family == AF_INET6) {
value = 1;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
&value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set IPv6 only (%d): %s\n",
errno, strerror(errno));
return -1;
}
}
value = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0) {
fprintf(stderr, "Unable to set REUSEADDR (%d): %s\n",
errno, strerror(errno));
return -1;
}
return 0;
}
+static int fragsize = 0;
+
static void parse_incoming_data(struct mmsghdr msg)
{
int i;
struct iovec *iov = msg.msg_hdr.msg_iov;
size_t iovlen = msg.msg_hdr.msg_iovlen;
union sctp_notification *snp;
if (!(msg.msg_hdr.msg_flags & MSG_NOTIFICATION)) {
if (msg.msg_len == 0) {
fprintf(stderr, "Received 0bytes packet\n");
exit(-1);
}
- /* check pckt len here */
- if (msg.msg_len != 65536) {
- fprintf(stderr, "KABOOM: %d\n", msg.msg_len);
- exit(-1);
+ if (!(msg.msg_hdr.msg_flags & MSG_EOR)) {
+ fprintf(stderr, "got a fragment size: %d\n", msg.msg_len);
+ fragsize = fragsize + msg.msg_len;
+ return;
+ }
+ if (fragsize) {
+ fragsize = fragsize + msg.msg_len;
+ fprintf(stderr, "Received all packets from frags: %d\n", fragsize);
+ if (fragsize != 65536) {
+ fprintf(stderr, "KABOOM: %d\n", msg.msg_len);
+ exit(-1);
+ }
+ fragsize = 0;
+ } else {
+ /* check pckt len here */
+ if (msg.msg_len != 65536) {
+ fprintf(stderr, "KABOOM: %d\n", msg.msg_len);
+ exit(-1);
+ }
}
return;
}
if (!(msg.msg_hdr.msg_flags & MSG_EOR)) {
fprintf(stderr, "[event] end of notifications\n");
return;
}
/* got a notification */
for (i=0; i< iovlen; i++) {
snp = iov[i].iov_base;
switch (snp->sn_header.sn_type) {
case SCTP_ASSOC_CHANGE:
fprintf(stderr, "[event] sctp assoc change\n");
break;
case SCTP_SHUTDOWN_EVENT:
fprintf(stderr, "[event] sctp shutdown event\n");
break;
case SCTP_SEND_FAILED:
fprintf(stderr, "[event] sctp send failed\n");
break;
case SCTP_PEER_ADDR_CHANGE:
fprintf(stderr, "[event] sctp peer addr change\n");
break;
case SCTP_REMOTE_ERROR:
fprintf(stderr, "[event] sctp remote error\n");
break;
default:
fprintf(stderr, "[event] unknown sctp event type: %hu\n", snp->sn_header.sn_type);
exit(-1);
break;
}
}
return;
}
void get_incoming_data(int sock, struct mmsghdr *msg)
{
int i, msg_recv;
msg_recv = recvmmsg(sock, msg, 256, MSG_DONTWAIT | MSG_NOSIGNAL, NULL);
if (msg_recv <= 0) {
fprintf(stderr, "Error message received from recvmmsg (%d): %s\n",
errno, strerror(errno));
exit(-1);
}
fprintf(stderr, "Received: %d messages\n", msg_recv);
for (i = 0; i < msg_recv; i++) {
parse_incoming_data(msg[i]);
}
}
-
int setup_rx_buffers(struct mmsghdr *msg)
{
int i;
struct sockaddr_storage addr[256];
struct iovec iov_in[256];
if (!msg) {
return -1;
}
/*
* Setup buffers
*/
for (i = 0; i < 256; i++) {
iov_in[i].iov_base = (void *)malloc(65536);
if (!iov_in[i].iov_base) {
fprintf(stderr, "Unable to malloc RX buffers(%d): %s\n",
errno, strerror(errno));
return -1;
}
memset(iov_in[i].iov_base, 0, 65536);
iov_in[i].iov_len = 65536;
memset(&msg[i].msg_hdr, 0, sizeof(struct msghdr));
msg[i].msg_hdr.msg_name = &addr[i];
msg[i].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
msg[i].msg_hdr.msg_iov = &iov_in[i];
msg[i].msg_hdr.msg_iovlen = 1;
}
return 0;
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Feb 24, 11:22 PM (18 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464519
Default Alt Text
(7 KB)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment