11 uint16_t maxInStreams ,
12 uint16_t maxAttempts ,
13 uint16_t maxInitTimeout )
16 setInitValues( numOutStreams, maxInStreams, maxAttempts, maxInitTimeout);
23int SCTPSocket::bind(
const std::vector<std::string>& localAddresses,
unsigned short localPort )
25 size_t size = localAddresses.size();
26 std::vector<sockaddr_in> dest(size);
28 for(
size_t i = 0; i < size; ++i)
29 fillAddress( localAddresses[i], localPort, dest[i]);
31 int ret = sctp_bindx(
m_socket,
reinterpret_cast<sockaddr*
>(dest.data()),
static_cast<int>(size), SCTP_BINDX_ADD_ADDR);
33 throw SocketException(
"Set of local address and port failed (sctp_bindx)");
37int SCTPSocket::connect(
const std::vector<std::string>& foreignAddresses,
unsigned short foreignPort )
39 size_t size = foreignAddresses.size();
40 std::vector<sockaddr_in> dest(size);
42 for(
size_t i = 0; i < size; ++i)
43 fillAddress( foreignAddresses[i], foreignPort, dest[i]);
46 int ret = sctp_connectx(
m_socket,
reinterpret_cast<sockaddr*
>(dest.data()),
static_cast<int>(size), 0);
56 struct sctp_status status;
57 socklen_t size =
sizeof(status);
58 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
60 return status.sstat_state;
65 struct sctp_status status;
66 socklen_t size =
sizeof(status);
67 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
69 return status.sstat_unackdata;
74 struct sctp_status status;
75 socklen_t size =
sizeof(status);
76 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
78 return status.sstat_penddata;
83 struct sctp_status status;
84 socklen_t size =
sizeof(status);
85 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
87 return status.sstat_instrms;
92 struct sctp_status status;
93 socklen_t size =
sizeof(status);
94 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
96 return status.sstat_outstrms;
101 struct sctp_status status;
102 socklen_t size =
sizeof(status);
103 if( getsockopt(
m_socket, IPPROTO_SCTP, SCTP_STATUS, &status, &size) < 0)
104 throw SocketException(
"SCTPSocket::fragmentationPoint failed (getsockopt)");
105 return status.sstat_fragmentation_point;
110 return std::string();
113int SCTPSocket::send(
const void* data,
size_t length, uint16_t stream,
unsigned ttl ,
unsigned context ,
116 int ret = sctp_sendmsg(
m_socket, data, length,
nullptr, 0, ppid, abort + switchAddr, stream, ttl, context);
119 else if (
static_cast<size_t>(ret) < length)
128 int ret = sctp_sendmsg(
m_socket, data, length,
nullptr, 0, ppid, abort + switchAddr + SCTP_UNORDERED, stream, ttl, context);
131 else if (
static_cast<size_t>(ret) < length)
138 struct sctp_sndrcvinfo info;
140 if( (ret = sctp_recvmsg(
m_socket, data, maxLen, 0, 0, &info, 0)) < 0)
142 stream = info.sinfo_stream;
148 struct sctp_sndrcvinfo info;
150 if( (ret = sctp_recvmsg(
m_socket, data, maxLen, 0, 0, &info, 0)) < 0)
152 stream = info.sinfo_stream;
161 poll.events = POLLIN | POLLPRI | POLLRDHUP;
165 if( ret == 0)
return 0;
166 if( ret < 0)
throw SocketException(
"SCTPSocket::timedReceive failed (poll)");
168 if( poll.revents & POLLRDHUP)
171 if( poll.revents & POLLIN || poll.revents & POLLPRI)
172 return receive( data, maxLen, stream);
181 poll.events = POLLIN | POLLPRI | POLLRDHUP;
185 if( ret == 0)
return 0;
186 if( ret < 0)
throw SocketException(
"SCTPSocket::timedReceive failed (poll)");
188 if( poll.revents & POLLRDHUP)
191 if( poll.revents & POLLIN || poll.revents & POLLPRI)
192 return receive( data, maxLen, stream, flag);
201 throw SocketException(
"listen failed, most likely another socket is already listening on the same port");
216 poll.events = POLLIN;
220 if( ret == 0)
return Handle();
221 if( ret < 0)
throw SocketException(
"SCTPSocket::timedAccept failed (poll)");
231 struct sctp_initmsg init;
232 init.sinit_num_ostreams = numOutStreams;
233 init.sinit_max_instreams = maxInStreams;
234 init.sinit_max_attempts = maxAttempts;
235 init.sinit_max_init_timeo = maxInitTimeout;
237 int ret = setsockopt(
m_socket, IPPROTO_SCTP, SCTP_INITMSG, &init,
sizeof(init));
#define TEMP_FAILURE_RETRY(expression)
InternetSocket(int sockfd)
create socket from a SocketHandle returned by an accept() call
static void fillAddress(std::string_view address, unsigned short port, sockaddr_in &addr)
unsigned outStreams() const
int sendUnordered(const void *data, size_t length, uint16_t stream, unsigned ttl=0, unsigned context=0, unsigned ppid=0, abortFlag abort=KEEPALIVE, switchAddressFlag switchAddr=KEEP_PRIMARY)
SCTPSocket(uint16_t numOutStreams=10, uint16_t maxInStreams=65535, uint16_t maxAttempts=4, uint16_t maxInitTimeout=0)
unsigned fragmentationPoint() const
void setInitValues(uint16_t ostr, uint16_t istr, uint16_t att, uint16_t time)
int connect(const std::vector< std::string > &foreignAddresses, unsigned short foreignPort=0)
unsigned inStreams() const
Handle timedAccept(int timeout) const
SocketHandle< SCTPSocket > Handle
Handle for a new socket returned by accept.
int receive(void *data, size_t maxLen, uint16_t &stream)
void listen(int backlog=5)
int send(const void *data, size_t length, uint16_t stream, unsigned ttl=0, unsigned context=0, unsigned ppid=0, abortFlag abort=KEEPALIVE, switchAddressFlag switchAddr=KEEP_PRIMARY)
int timedReceive(void *data, size_t maxLen, uint16_t &stream, int timeout)
int bind(const std::vector< std::string > &localAddresses, unsigned short localPort=0)
std::string primaryAddress() const
Signals a problem with the execution of a socket call.