-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsctp_client_I_FORWARD.c
More file actions
109 lines (95 loc) · 3.24 KB
/
sctp_client_I_FORWARD.c
File metadata and controls
109 lines (95 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <signal.h>
#include "header.h"
void sigintHandler(int sig) {
system("sudo ip netns exec 'server' iptables -D INPUT -p sctp -m length --length 500:4000 -j DROP");
printf("unblocked\n");
fflush(stdout);
exit(EXIT_SUCCESS);
}
int main ()
{
signal(SIGINT, sigintHandler);
char *send_msg =
#include "input_text"
char *msg2 =
#include "input_text"
char *msg3 =
#include "input_text"
int sd, frag_interleave;
struct sockaddr_in addr;
size_t recv_len;
char buf[BUFSIZ];
struct msghdr msg[1];
struct iovec iov[1];
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sri;
struct sctp_assoc_value assoc;
char cbuf[sizeof (*cmsg) + sizeof (*sri)];
union sctp_notification *snp;
/* Initialize the message header for receiving */
memset(msg, 0, sizeof (*msg));
msg->msg_control = cbuf;
msg->msg_controllen = sizeof (*cmsg) + sizeof (*sri);
msg->msg_flags = 0;
cmsg = (struct cmsghdr *)cbuf;
sri = (struct sctp_sndrcvinfo *)(cmsg + 1);
iov->iov_base = buf;
iov->iov_len = BUFSIZ;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
handle_error((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0, "create socket")
/* enable interleave support */
frag_interleave = 2;
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &frag_interleave, sizeof(frag_interleave)) != 0,
"set frag interleave"
)
memset(&assoc, 0, sizeof(struct sctp_assoc_value));
assoc.assoc_value = 1;
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_INTERLEAVING_SUPPORTED, &assoc, sizeof(assoc)) != 0,
"enable interleave"
)
addr.sin_family = AF_INET;
addr.sin_port = htons(SERVER_PORT);
handle_error(inet_pton(AF_INET, SERVER_ADDR, &addr.sin_addr) <= 0, "inet_pton")
handle_error(sctp_connectx(sd, (struct sockaddr*)&addr, 1, NULL) != 0, "sctp_connectx")
/* use iptable to block communication here */
system("sudo ip netns exec 'server' iptables -A INPUT -p sctp -m length --length 500:4000 -j DROP");
printf("blocked\n");
fflush(stdout);
/* support I-FORWARD */
sri->sinfo_flags = SCTP_PR_SCTP_RTX;
sri->sinfo_timetolive = 2;
// sri->sinfo_flags = SCTP_PR_SCTP_TTL;
// sri->sinfo_timetolive = 1000;
handle_error(
sctp_sendmsg(sd, send_msg, (size_t)strlen(send_msg) + 1,
(struct sockaddr*)&addr, sizeof(struct sockaddr_in),
0, sri->sinfo_flags, 0, sri->sinfo_timetolive, 0) < 0,
"sctp_sendmsg",
close(sd);
)
handle_error(
sctp_sendmsg(sd, msg2, (size_t)strlen(msg2) + 1,
(struct sockaddr*)&addr, sizeof(struct sockaddr_in),
0, sri->sinfo_flags, 0, sri->sinfo_timetolive, 0) < 0,
"sctp_sendmsg",
close(sd);
)
handle_error(
sctp_sendmsg(sd, msg3, (size_t)strlen(msg3) + 1,
(struct sockaddr*)&addr, sizeof(struct sockaddr_in),
0, sri->sinfo_flags, 0, sri->sinfo_timetolive, 0) < 0,
"sctp_sendmsg",
close(sd);
)
/* unreachable */
handle_error((recv_len = recvmsg(sd, msg, 0)) < 0, "recvmsg", close(sd);)
printf("server msg: %s\n", msg->msg_iov->iov_base);
system("sudo ip netns exec 'server' iptables -D INPUT -p sctp -m length --length 500:4000 -j DROP");
printf("unblocked\n");
fflush(stdout);
close(sd);
exit(EXIT_SUCCESS);
}