-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsctp_client_RE_CONFIG.c
More file actions
111 lines (98 loc) · 3.36 KB
/
sctp_client_RE_CONFIG.c
File metadata and controls
111 lines (98 loc) · 3.36 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
110
111
#include "header.h"
#define STREAM_NUM 4
#define ADD_STREAM 1
int main ()
{
char *send_msg;
int sd;
struct sockaddr_in addr;
size_t recv_len;
sctp_assoc_t assoc_id;
char buf[BUFFER_SIZE];
struct msghdr msg[1];
struct iovec iov[1];
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sri;
struct sctp_assoc_value assoc;
struct sctp_reset_streams *srs;
struct sctp_add_streams *sas;
char cbuf[sizeof (*cmsg) + sizeof (*sri)];
/* 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 = BUFFER_SIZE;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
handle_error((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0, "create socket")
/* enable settings */
memset(&assoc, 0, sizeof(struct sctp_assoc_value));
assoc.assoc_id = 0;
assoc.assoc_value = (SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_RESET_ASSOC_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ);
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &assoc, sizeof(assoc)) != 0,
"enable reset"
)
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")
/* reset I/O streams */
send_msg = "reset I/O";
srs = (struct sctp_reset_streams*) malloc(sizeof(sctp_assoc_t) + (2 + STREAM_NUM) * sizeof(uint16_t));
srs->srs_assoc_id = 0;
srs->srs_number_streams = STREAM_NUM;
for (int i = 0; i < srs->srs_number_streams; ++i) {
srs->srs_stream_list[i] = i;
}
srs->srs_flags = (SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_OUTGOING);
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_RESET_STREAMS, srs,
(socklen_t)(sizeof(sctp_assoc_t) + (2 + STREAM_NUM) * sizeof(uint16_t))) != 0,
"reset streams"
)
handle_error(
sctp_sendmsg(sd, send_msg, (size_t)strlen(send_msg) + 1, NULL, 0, 0, 0, 0, 0, 0) < 0,
"sctp_sendmsg",
close(sd);
)
handle_error((recv_len = recvmsg(sd, msg, 0)) < 0, "recvmsg", close(sd);)
printf("server msg: %s\n", msg->msg_iov->iov_base);
/* reset assoc */
send_msg = "reset assoc";
assoc_id = 0;
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_RESET_ASSOC, &assoc_id, sizeof(socklen_t)) != 0,
"reset assoc"
)
handle_error(
sctp_sendmsg(sd, send_msg, (size_t)strlen(send_msg) + 1, NULL, 0, 0, 0, 0, 0, 0) < 0,
"sctp_sendmsg",
close(sd);
)
handle_error((recv_len = recvmsg(sd, msg, 0)) < 0, "recvmsg", close(sd);)
printf("server msg: %s\n", msg->msg_iov->iov_base);
/* add stream */
send_msg = "add stream";
sas = (struct sctp_add_streams *)malloc(sizeof(struct sctp_add_streams));
sas->sas_assoc_id = 0;
sas->sas_instrms = ADD_STREAM;
sas->sas_outstrms= ADD_STREAM;
handle_error(
setsockopt(sd, IPPROTO_SCTP, SCTP_ADD_STREAMS, sas, (socklen_t)sizeof(struct sctp_add_streams)) != 0,
"add stream"
)
handle_error(
sctp_sendmsg(sd, send_msg, (size_t)strlen(send_msg) + 1, NULL, 0, 0, 0, 0, 0, 0) < 0,
"sctp_sendmsg",
close(sd);
)
handle_error((recv_len = recvmsg(sd, msg, 0)) < 0, "recvmsg", close(sd);)
printf("server msg: %s\n", msg->msg_iov->iov_base);
close(sd);
exit(EXIT_SUCCESS);
}