Last active
April 21, 2024 09:13
-
-
Save nomis/b125c3885c937917078886fd4ad0f946 to your computer and use it in GitHub Desktop.
dtee, implemented using sctp
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
$ make LDLIBS=-lsctp sctp | |
g++ sctp.cpp -lsctp -o sctp | |
$ ./sctp | |
flags 32896 assoc_id 0 stream 0 port 42417 len 20 | |
flags 32896 assoc_id 0 stream 0 port 49898 len 20 | |
flags 128 assoc_id 132 stream 0 port 42417 len 1 data o | |
flags 128 assoc_id 132 stream 0 port 42417 len 2 data OO | |
flags 128 assoc_id 134 stream 0 port 49898 len 1 data e | |
flags 128 assoc_id 134 stream 0 port 49898 len 2 data EE | |
flags 128 assoc_id 134 stream 0 port 49898 len 1 data e | |
flags 128 assoc_id 134 stream 0 port 49898 len 2 data EE | |
flags 128 assoc_id 132 stream 0 port 42417 len 1 data o | |
flags 128 assoc_id 132 stream 0 port 42417 len 2 data OO |
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 <errno.h> | |
#include <netinet/in.h> | |
#include <netinet/sctp.h> | |
#include <stdio.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <iostream> | |
int main() { | |
int si = -1; | |
int so = -1; | |
int se = -1; | |
struct sockaddr_in ai{}; | |
struct sockaddr_in ao{}; | |
struct sockaddr_in ae{}; | |
struct sockaddr_in am{}; | |
socklen_t li = sizeof(ai); | |
socklen_t lo = sizeof(ao); | |
socklen_t le = sizeof(ae); | |
socklen_t lm; | |
pid_t pid = getpid(); | |
struct sctp_event_subscribe ei{}; | |
ai.sin_family = AF_INET; | |
ai.sin_addr.s_addr = htonl(0x7F000000 | (pid & 0xFFFFFF)); | |
ao.sin_family = AF_INET; | |
ao.sin_addr.s_addr = htonl(0x7F000000 | (pid & 0xFFFFFF)); | |
ae.sin_family = AF_INET; | |
ae.sin_addr.s_addr = htonl(0x7F000000 | (pid & 0xFFFFFF)); | |
si = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); | |
if (si == -1) { | |
perror("socket"); | |
return 1; | |
} | |
so = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); | |
if (so == -1) { | |
perror("socket"); | |
return 1; | |
} | |
se = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); | |
if (se == -1) { | |
perror("socket"); | |
return 1; | |
} | |
if (bind(si, reinterpret_cast<struct sockaddr*>(&ai), sizeof(ai)) == -1) { | |
perror("bind"); | |
return 1; | |
} | |
if (bind(so, reinterpret_cast<struct sockaddr*>(&ao), sizeof(ao)) == -1) { | |
perror("bind"); | |
return 1; | |
} | |
if (bind(se, reinterpret_cast<struct sockaddr*>(&ae), sizeof(ae)) == -1) { | |
perror("bind"); | |
return 1; | |
} | |
if (getsockname(si, reinterpret_cast<struct sockaddr*>(&ai), &li) == -1) { | |
perror("getsockname"); | |
return 1; | |
} | |
if (getsockname(so, reinterpret_cast<struct sockaddr*>(&ao), &lo) == -1) { | |
perror("getsockname"); | |
return 1; | |
} | |
if (getsockname(se, reinterpret_cast<struct sockaddr*>(&ae), &le) == -1) { | |
perror("getsockname"); | |
return 1; | |
} | |
ei.sctp_association_event = 1; | |
ei.sctp_data_io_event = 1; | |
if (setsockopt(si, IPPROTO_SCTP, SCTP_EVENTS, &ei, sizeof(ei)) == -1) { | |
perror("setsockopt"); | |
return 1; | |
} | |
if (listen(si, 2) == -1) { | |
perror("listen"); | |
return 1; | |
} | |
if (connect(so, reinterpret_cast<struct sockaddr*>(&ai), lo) == -1) { | |
perror("connect"); | |
return 1; | |
} | |
if (connect(se, reinterpret_cast<struct sockaddr*>(&ai), le) == -1) { | |
perror("connect"); | |
return 1; | |
} | |
write(so, "o", 1); | |
write(so, "OO", 2); | |
write(so, "o", 1); | |
write(so, "OO", 2); | |
write(se, "e", 1); | |
write(se, "EE", 2); | |
write(se, "e", 1); | |
write(se, "EE", 2); | |
while (true) { | |
char buf[4096] = { 0 }; | |
struct sctp_sndrcvinfo info{}; | |
int flags; | |
int len; | |
lm = sizeof(am); | |
flags = 0; | |
len = sctp_recvmsg(si, buf, sizeof(buf), reinterpret_cast<struct sockaddr *>(&am), &lm, &info, &flags); | |
if (len == -1) { | |
perror("sctp_recvmsg"); | |
return 1; | |
} | |
std::cout | |
<< "flags " << flags | |
<< " assoc_id " << info.sinfo_assoc_id | |
<< " stream " << info.sinfo_stream | |
<< " port " << am.sin_port | |
<< " len " << len; | |
if (!(flags & MSG_NOTIFICATION)) { | |
if (len > 0) | |
std::cout << " data "; | |
for (int i = 0; i < len; i++ ) { | |
std::cout << buf[i]; | |
} | |
} | |
std::cout << std::endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment