00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "C_SocketSCTP.hpp"
00020 #include "Utils.hpp"
00021
00022 #include "iostream_t.hpp"
00023
00024 #include <cerrno>
00025 #include <cstring>
00026 #include <unistd.h>
00027 #include <fcntl.h>
00028
00029 #define BUFLEN 1024
00030 #define DECODEBUFLEN 2048
00031 #define MSGFLAG 0
00032 #define MAX_OUTGOING 128
00033 #define MAX_INCOMING 128
00034
00035 #define SOCKET_ERROR(l,m) iostream_error << m << iostream_endl << iostream_flush
00036
00037 #ifdef DEBUG_MODE
00038 #define SOCKET_DEBUG(l,m) iostream_error << m << iostream_endl << iostream_flush
00039 #else
00040 #define SOCKET_DEBUG(l,m)
00041 #endif
00042
00043 C_SocketSCTP::C_SocketSCTP(int P_channel_id) {
00044 SOCKET_DEBUG(1, "C_SocketSCTP::C_SocketSCTP ("
00045 << P_channel_id
00046 << ") id="
00047 << m_socket_id);
00048 m_socket_id = -1 ;
00049 m_channel_id = P_channel_id ;
00050 m_state = E_SOCKET_STATE_NOT_READY ;
00051 m_decode = NULL ;
00052 m_recv_msg_list = NULL ;
00053 m_recv_buflen = BUFLEN ;
00054 ALLOC_TABLE(m_recv_buf, char*, sizeof(char), BUFLEN);
00055 }
00056
00057 C_SocketSCTP::C_SocketSCTP(T_SocketType P_type,
00058 int P_port,
00059 int P_channel_id) {
00060
00061 SOCKET_DEBUG(1, "C_SocketSCTP::C_SocketSCTP ("
00062 << P_port << "," << P_channel_id << ") id=" << m_socket_id);
00063
00064 m_socket_id = -1 ;
00065 m_type = P_type ;
00066 m_src_port = P_port ;
00067 m_channel_id = P_channel_id ;
00068 m_state = E_SOCKET_STATE_NOT_READY ;
00069 m_recv_buflen = BUFLEN ;
00070 ALLOC_TABLE(m_recv_buf, char*, sizeof(char), BUFLEN);
00071 m_decode = NULL ;
00072 m_recv_msg_list = NULL ;
00073 }
00074
00075 C_SocketSCTP::C_SocketSCTP(T_SocketType P_type,
00076 int P_channel_id) {
00077
00078 SOCKET_DEBUG(1, "C_SocketSCTP::C_SocketSCTP ("
00079 << P_channel_id << ") id=" << m_socket_id);
00080 m_socket_id = -1 ;
00081 m_type = P_type ;
00082 m_channel_id = P_channel_id ;
00083 m_state = E_SOCKET_STATE_NOT_READY ;
00084 m_recv_buflen = BUFLEN ;
00085 ALLOC_TABLE(m_recv_buf, char*, sizeof(char), BUFLEN);
00086 m_decode = NULL ;
00087 m_recv_msg_list = NULL ;
00088 }
00089
00090 C_pSCTPDataDecode C_SocketSCTP::get_decode() {
00091 return (m_decode);
00092 }
00093 C_ProtocolBinaryFrame* C_SocketSCTP::get_protocol() {
00094 return (m_protocol);
00095 }
00096 T_pRcvMsgCtxtList C_SocketSCTP::get_list() {
00097 return (m_recv_msg_list);
00098 }
00099
00100 void C_SocketSCTP::set_channel_id(int P_channel_id) {
00101 SOCKET_DEBUG(1, "C_SocketSCTP::set_channel_id(" << P_channel_id << ") id="
00102 << m_socket_id);
00103 m_channel_id = P_channel_id ;
00104 }
00105
00106 int C_SocketSCTP::_open(int P_socket_domain,
00107 size_t P_buffer_size,
00108 C_ProtocolBinaryFrame *P_protocol) {
00109
00110 int L_socketSCTP_type ;
00111 int L_socket_domain ;
00112
00113 SOCKET_DEBUG(1, "C_SocketSCTP::_open ()");
00114
00115 m_buffer_size = P_buffer_size ;
00116 L_socket_domain = P_socket_domain ;
00117
00118
00119 switch (m_type) {
00120 case E_SOCKET_TCP_MODE:
00121 L_socketSCTP_type = SOCK_STREAM ;
00122 break ;
00123 case E_SOCKET_UDP_MODE:
00124 L_socketSCTP_type = SOCK_DGRAM ;
00125 break ;
00126 default:
00127 SOCKET_ERROR(0, "Unsupported transport type");
00128 exit (1);
00129 }
00130
00131
00132
00133 m_socket_id = call_socket(L_socket_domain, L_socketSCTP_type, IPPROTO_SCTP);
00134
00135 SOCKET_DEBUG(1, "m_socket_id [" << m_socket_id << "]");
00136
00137 if (m_socket_id < 0) {
00138 perror("allocation failed");
00139 } else {
00140 set_properties() ;
00141 }
00142
00143 m_protocol = P_protocol ;
00144
00145 return (0) ;
00146 }
00147
00148 C_SocketSCTP::~C_SocketSCTP() {
00149 FREE_TABLE(m_recv_buf);
00150 SOCKET_DEBUG(1, "C_SocketSCTP::~C_SocketSCTP ()");
00151 }
00152
00153 int C_SocketSCTP::get_id () {
00154 SOCKET_DEBUG(1, "C_SocketSCTP::get_id ()");
00155 return (m_socket_id);
00156 }
00157
00158 int C_SocketSCTP::get_channel_id () {
00159 SOCKET_DEBUG(1, "C_SocketSCTP::get_channel_id ()");
00160 return (m_channel_id);
00161 }
00162
00163 void C_SocketSCTP::_close () {
00164 SOCKET_DEBUG(1, "C_SocketSCTP::_close ()");
00165 call_shutdown(m_socket_id, SHUT_RDWR);
00166 if (call_close(m_socket_id) != 0) {
00167 SOCKET_ERROR(0,
00168 "close socket ["
00169 << m_socket_id
00170 << "] failed ["
00171 << errno
00172 << "] ["
00173 << strerror(errno)
00174 << "]");
00175 }
00176 }
00177
00178
00179 void C_SocketSCTP::set_fd_set(fd_set *P_rSet, fd_set *P_wSet) {
00180 SOCKET_DEBUG(1, "C_SocketSCTP::set_fd_set () id=" << m_socket_id);
00181 switch (m_state) {
00182 case E_SOCKET_STATE_READY:
00183 FD_SET(m_socket_id, P_rSet);
00184 break ;
00185 case E_SOCKET_STATE_INPROGESS:
00186 FD_SET(m_socket_id, P_rSet);
00187
00188 break ;
00189 case E_SOCKET_STATE_NOT_READY:
00190 break ;
00191 }
00192 }
00193
00194 void C_SocketSCTP::set_properties() {
00195
00196
00197 unsigned int L_max_buf_size ;
00198 struct linger L_linger ;
00199 int L_flags ;
00200
00201 SOCKET_DEBUG(1, "C_SocketSCTP::set_properties()");
00202 if (m_type == E_SOCKET_TCP_MODE) {
00203
00204 L_linger.l_onoff = 1;
00205 L_linger.l_linger = 0;
00206 if (call_setsockopt (m_socket_id, SOL_SOCKET, SO_LINGER,
00207 &L_linger, sizeof (L_linger)) < 0) {
00208 SOCKET_ERROR(1, "Unable to set SO_LINGER option");
00209 }
00210 }
00211
00212
00213 {
00214 struct sctp_initmsg init;
00215 sctp_event_subscribe events;
00216
00217
00218 init.sinit_num_ostreams = MAX_OUTGOING;
00219 init.sinit_max_instreams = MAX_INCOMING;
00220 init.sinit_max_attempts = 3;
00221 init.sinit_max_init_timeo = 30;
00222 if(call_setsockopt(m_socket_id, IPPROTO_SCTP,
00223 SCTP_INITMSG, (void*)&init, sizeof(init)) < 0) {
00224 SOCKET_ERROR(1, "Unable to set SCTP_INITMSG option");
00225 }
00226
00227 events.sctp_data_io_event = 1;
00228 events.sctp_association_event = 1;
00229 events.sctp_address_event = 1;
00230 events.sctp_send_failure_event = 1;
00231 events.sctp_peer_error_event = 1;
00232 events.sctp_shutdown_event = 1;
00233 events.sctp_partial_delivery_event = 1;
00234 events.sctp_adaption_layer_event = 1;
00235
00236 if(call_setsockopt(m_socket_id, IPPROTO_SCTP,
00237 SCTP_EVENTS,&events,sizeof(events)) < 0) {
00238 SOCKET_ERROR(1, "Unable to set SCTP_EVENTS option");
00239 }
00240
00241
00242
00243 }
00244
00245
00246 L_max_buf_size = m_buffer_size ;
00247 if(call_setsockopt(m_socket_id, SOL_SOCKET, SO_SNDBUF,
00248 &L_max_buf_size, sizeof(L_max_buf_size))) {
00249 SOCKET_ERROR(1,"Unable to set socket sndbuf");
00250 }
00251
00252
00253 L_max_buf_size = m_buffer_size ;
00254 if(call_setsockopt(m_socket_id, SOL_SOCKET, SO_RCVBUF,
00255 &L_max_buf_size, sizeof(L_max_buf_size))) {
00256 SOCKET_ERROR(1, "Unable to set socket rcvbuf");
00257 }
00258
00259
00260 L_flags = call_fcntl(m_socket_id, F_GETFL , NULL);
00261 L_flags |= O_NONBLOCK;
00262 call_fcntl(m_socket_id, F_SETFL , L_flags);
00263
00264 }
00265
00266 C_SocketSCTPListen::C_SocketSCTPListen(T_SocketType P_type,
00267 T_pIpAddr P_addr,
00268 int P_channel_id)
00269 : C_SocketSCTP(P_type, P_channel_id) {
00270 SOCKET_DEBUG(0, "C_SocketSCTPListen::C_SocketSCTPListen() id=" << m_socket_id);
00271 m_source_addr_info = P_addr ;
00272 }
00273
00274
00275 C_SocketSCTPListen::~C_SocketSCTPListen() {
00276 SOCKET_DEBUG(0, "C_SocketSCTPListen::~C_SocketSCTPListen() id=" << m_socket_id);
00277 }
00278
00279 size_t C_SocketSCTPListen::received_buffer (unsigned char *P_data,
00280 size_t P_size_buf,
00281 struct timeval *P_time) {
00282 SOCKET_DEBUG(0, "C_SocketSCTPListen::received_buffer() id=" << m_socket_id);
00283 return (0);
00284 }
00285
00286 int C_SocketSCTPListen::_open (size_t P_buffer_size,
00287 C_ProtocolBinaryFrame *P_protocol) {
00288
00289 int L_rc ;
00290
00291 SOCKET_DEBUG(0, "C_SocketSCTPListen::_open()");
00292
00293 L_rc = C_SocketSCTP::_open(get_domain(m_source_addr_info),
00294 P_buffer_size,
00295 P_protocol) ;
00296
00297 if (L_rc == 0) {
00298
00299
00300
00301
00302 L_rc = call_bind(m_socket_id,
00303 (sockaddr *)(void *)&(m_source_addr_info->m_addr),
00304 SOCKADDR_IN_SIZE(&(m_source_addr_info->m_addr)));
00305
00306 if (L_rc) {
00307 SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
00308 } else {
00309
00310 if (m_type == E_SOCKET_TCP_MODE) {
00311
00312
00313
00314
00315
00316 L_rc = call_listen(m_socket_id, 5);
00317
00318
00319 if (L_rc) {
00320 SOCKET_ERROR(1, "listen [" << strerror(errno) << "]");
00321 }
00322 }
00323
00324 m_state = E_SOCKET_STATE_READY ;
00325 }
00326 }
00327
00328 return (L_rc);
00329
00330 }
00331
00332 C_SocketSCTP* C_SocketSCTPListen::process_fd_set (fd_set *P_rSet,
00333 fd_set *P_wSet,
00334 C_TransportEvent *P_event) {
00335
00336 C_SocketSCTPServer *L_socket = NULL ;
00337 int L_ret ;
00338
00339 SOCKET_DEBUG(0, "C_SocketSCTPListen::process_fd_set() id=" << m_socket_id);
00340
00341
00342 if (FD_ISSET(m_socket_id, P_rSet)) {
00343 NEW_VAR(L_socket, C_SocketSCTPServer(this, m_channel_id));
00344 L_ret = L_socket->_open(m_buffer_size, m_protocol) ;
00345 if (L_ret == 0) {
00346 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() CNX");
00347 P_event->m_type = C_TransportEvent::E_TRANS_CONNECTION ;
00348 P_event->m_channel_id = m_channel_id ;
00349 P_event->m_id = L_socket->get_id() ;
00350 } else {
00351 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() NOEVENT open failed");
00352 DELETE_VAR(L_socket);
00353 P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00354 }
00355 } else {
00356 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() NOEVENT");
00357 P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00358 }
00359
00360 return (L_socket);
00361 }
00362
00363 T_SockAddrStorage* C_SocketSCTPListen::get_source_address() {
00364 return(&(m_source_addr_info->m_addr));
00365 }
00366
00367 C_SocketSCTPServer::C_SocketSCTPServer(C_SocketSCTPListen *P_listen,
00368 int P_channel_id)
00369 : C_SocketSCTPWithData(P_channel_id) {
00370 SOCKET_DEBUG(0, "C_SocketSCTPServer::C_SocketSCTPServer() id=" << m_socket_id);
00371 m_listen_sock = P_listen ;
00372 }
00373
00374 C_SocketSCTPServer::~C_SocketSCTPServer() {
00375 SOCKET_DEBUG(0, "C_SocketSCTPServer::~C_SocketSCTPServer() id=" << m_socket_id);
00376 }
00377
00378 int C_SocketSCTPServer::_open(size_t P_buffer_size,
00379 C_ProtocolBinaryFrame *P_protocol) {
00380
00381 tool_socklen_t L_size ;
00382 int L_rc = 0 ;
00383
00384 SOCKET_DEBUG(0, "C_SocketSCTPServer::_open()");
00385
00386 L_size = SOCKADDR_IN_SIZE(m_listen_sock->get_source_address());
00387 memset(&m_accepted_addr, 0, L_size);
00388
00389 m_socket_id = call_accept (m_listen_sock->get_id(),
00390 (sockaddr *)(void *)&m_accepted_addr,
00391 &L_size);
00392
00393 m_protocol = P_protocol ;
00394
00395 m_buffer_size = P_buffer_size ;
00396
00397 set_properties () ;
00398
00399 if (m_socket_id < 0) {
00400 SOCKET_ERROR(0, "accept failed for listen [" << m_listen_sock->get_id()
00401 << "] [" << strerror(errno) << "]");
00402 L_rc = -1 ;
00403 } else {
00404 m_state = E_SOCKET_STATE_READY ;
00405 }
00406
00407 return (L_rc);
00408 }
00409
00410 C_SocketSCTPClient::C_SocketSCTPClient(T_SocketType P_type,
00411 T_pIpAddr P_addr,
00412 int P_channel_id)
00413 : C_SocketSCTPWithData(P_type, P_addr, P_channel_id) {
00414 SOCKET_DEBUG(0, "C_SocketSCTPClient::C_SocketSCTPClient() id=" << m_socket_id);
00415 }
00416
00417 C_SocketSCTPClient::~C_SocketSCTPClient() {
00418 SOCKET_DEBUG(0, "C_SocketSCTPClient::~C_SocketSCTPClient() id=" << m_socket_id);
00419 }
00420
00421 int C_SocketSCTPClient::_open(T_pOpenStatus P_status,
00422 size_t P_buffer_size,
00423 C_ProtocolBinaryFrame *P_protocol) {
00424
00425 int L_rc = 0 ;
00426
00427 SOCKET_DEBUG(0, "C_SocketSCTPClient::_open()");
00428 L_rc = C_SocketSCTP::_open(get_domain(m_remote_addr_info),
00429 P_buffer_size,
00430 P_protocol) ;
00431
00432 if (L_rc == 0) {
00433
00434 L_rc = call_connect (m_socket_id,
00435 (struct sockaddr*)(void*)&(m_remote_addr_info->m_addr),
00436 SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ;
00437 if (L_rc) {
00438 if (errno != EINPROGRESS) {
00439 SOCKET_ERROR(1, "connect failed ["
00440 << L_rc << "]["
00441 << strerror(errno) << "]");
00442 *P_status = E_OPEN_FAILED ;
00443 } else {
00444 m_state = E_SOCKET_STATE_INPROGESS ;
00445 *P_status = E_OPEN_DELAYED ;
00446 L_rc = 0 ;
00447 }
00448
00449 } else {
00450 m_state = E_SOCKET_STATE_READY ;
00451 *P_status = E_OPEN_OK ;
00452 }
00453 }
00454 return (L_rc);
00455 }
00456
00457 C_SocketSCTPWithData::C_SocketSCTPWithData(int P_channel_id)
00458 : C_SocketSCTP (P_channel_id) {
00459 SOCKET_DEBUG(0, "C_SocketSCTPWithData::C_SocketSCTPWithData() id=" << m_socket_id);
00460 m_data_queue.clear();
00461 m_data_recv = false ;
00462 NEW_VAR(m_decode, C_SCTPDataDecode(DECODEBUFLEN));
00463 NEW_VAR(m_recv_msg_list, T_RcvMsgCtxtList());
00464 m_recv_msg_list->clear();
00465 }
00466
00467 C_SocketSCTPWithData::C_SocketSCTPWithData(T_SocketType P_type,
00468 T_pIpAddr P_addr,
00469 int P_channel_id)
00470 : C_SocketSCTP (P_type, P_channel_id) {
00471 SOCKET_DEBUG(0, "C_SocketSCTPWithData::C_SocketSCTPWithData() id=" << m_socket_id);
00472 m_data_queue.clear();
00473 m_remote_addr_info = P_addr;
00474 NEW_VAR(m_decode, C_SCTPDataDecode(DECODEBUFLEN));
00475 NEW_VAR(m_recv_msg_list, T_RcvMsgCtxtList());
00476 m_recv_msg_list->clear();
00477 }
00478
00479
00480 C_SocketSCTPWithData::~C_SocketSCTPWithData() {
00481 SOCKET_DEBUG(0, "C_SocketSCTPWithData::~C_SocketSCTPWithData()");
00482 if (!m_data_queue.empty()) {
00483 m_data_queue.erase(m_data_queue.begin(), m_data_queue.end());
00484 }
00485 DELETE_VAR(m_decode);
00486 if (!m_recv_msg_list->empty()) {
00487
00488 m_recv_msg_list->erase(m_recv_msg_list->begin(),
00489 m_recv_msg_list->end());
00490 }
00491 DELETE_VAR(m_recv_msg_list);
00492 }
00493
00494 void C_SocketSCTPWithData::sctp_event_handler (C_TransportEvent *P_event) {
00495
00496 struct sctp_assoc_change *sac;
00497 struct sctp_send_failed *ssf;
00498 struct sctp_paddr_change *spc;
00499 struct sctp_remote_error *sre;
00500 union sctp_notification *snp;
00501
00502
00503 struct sockaddr_in *sin;
00504 struct sockaddr_in6 *sin6;
00505
00506 snp = (union sctp_notification *)m_recv_buf;
00507
00508 switch (snp->sn_header.sn_type) {
00509
00510 case SCTP_ASSOC_CHANGE:
00511 sac = &snp->sn_assoc_change;
00512 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler()" <<
00513 "EVENT assoc_change: state="
00514 << sac->sac_state
00515 <<", error="
00516 << sac->sac_error
00517 <<", instr="
00518 << sac->sac_inbound_streams
00519 <<", outstr="
00520 << sac->sac_outbound_streams);
00521
00522 switch(sac->sac_state) {
00523 case SCTP_COMM_UP:
00524 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00525 "ASSOC EVENT: COMMUNICATION UP");
00526
00527 switch (m_state) {
00528 case E_SOCKET_STATE_INPROGESS:
00529 m_state = E_SOCKET_STATE_READY ;
00530 P_event->m_type = C_TransportEvent::E_TRANS_OPEN ;
00531 P_event->m_channel_id = m_channel_id ;
00532 P_event->m_id = m_socket_id ;
00533 break ;
00534 default:
00535 break ;
00536 }
00537 break;
00538
00539 case SCTP_COMM_LOST:
00540 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00541 "ASSOC EVENT: COMMUNICATION LOST");
00542 switch (m_state) {
00543
00544 case E_SOCKET_STATE_READY:
00545 P_event->m_type = C_TransportEvent::E_TRANS_CLOSED ;
00546 P_event->m_channel_id = m_channel_id ;
00547 P_event->m_id = m_socket_id ;
00548 break ;
00549
00550 case E_SOCKET_STATE_INPROGESS:
00551 P_event->m_type = C_TransportEvent::E_TRANS_OPEN_FAILED ;
00552 P_event->m_channel_id = m_channel_id ;
00553 P_event->m_id = m_socket_id ;
00554 break;
00555
00556 default:
00557 break ;
00558 }
00559 break ;
00560 case SCTP_RESTART:
00561 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00562 "ASSOC EVENT: RESTART");
00563 break;
00564 case SCTP_SHUTDOWN_COMP:
00565 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00566 "ASSOC EVENT: SHUTDOWN COMPLETE");
00567 break;
00568 case SCTP_CANT_STR_ASSOC:
00569 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00570 "ASSOC EVENT: CANT START ASSOC "
00571 << (uint32_t)sac->sac_assoc_id);
00572 exit(0);
00573 break;
00574 default:
00575 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00576 "ASSOC EVENT: UNKNOWN");
00577 break ;
00578 }
00579
00580 break;
00581
00582 case SCTP_SEND_FAILED:
00583 ssf = &snp->sn_send_failed;
00584 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00585 "EVENT sendfailed: len="
00586 << ssf->ssf_length
00587 << " err=" << ssf->ssf_error);
00588 break;
00589
00590 case SCTP_PEER_ADDR_CHANGE:
00591 spc = &snp->sn_paddr_change;
00592
00593 switch(spc->spc_state) {
00594 case SCTP_ADDR_REACHABLE:
00595 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00596 "ASSOC PEER: ADDRESS REACHABLE");
00597 break;
00598 case SCTP_ADDR_UNREACHABLE:
00599 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00600 "ASSOC PEER: ADDRESS UNAVAILABLE");
00601 break;
00602 case SCTP_ADDR_REMOVED:
00603 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00604 "ASSOC PEER: ADDRESS REMOVED");
00605 break;
00606 case SCTP_ADDR_ADDED:
00607 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00608 "ASSOC PEER: ADDRESS ADDED");
00609 break;
00610 case SCTP_ADDR_MADE_PRIM:
00611 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00612 "ASSOC PEER: ADDRESS MADE PRIMARY");
00613 break;
00614 case SCTP_ADDR_CONFIRMED:
00615 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00616 "ASSOC PEER: ADDRESS CONFIRMED");
00617 break;
00618 default:
00619 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00620 "ASSOC PEER: UNKNOWN");
00621 break ;
00622 }
00623
00624 if (spc->spc_aaddr.ss_family == AF_INET) {
00625 sin = (struct sockaddr_in *)&spc->spc_aaddr;
00626
00627 } else {
00628 sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
00629
00630 }
00631
00632
00633 break;
00634
00635 case SCTP_REMOTE_ERROR:
00636 sre = &snp->sn_remote_error;
00637
00638 break;
00639
00640 case SCTP_ADAPTION_INDICATION:
00641 SOCKET_DEBUG(0, "C_SocketSCTPWithData::sctp_event_handler() " <<
00642 "EVENT: ADAPTATION INDICATION");
00643 break;
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 case SCTP_SHUTDOWN_EVENT:
00658 SOCKET_DEBUG(0,
00659 "C_SocketSCTPWithData::sctp_event_handler() EVENT shutdown");
00660 break;
00661
00662 default:
00663 SOCKET_DEBUG(0,
00664 "C_SocketSCTPWithData::sctp_event_handler() EVENT unknown "
00665 << snp->sn_header.sn_type);
00666 break;
00667 }
00668
00669 }
00670
00671 bool C_SocketSCTPWithData::sctp_recv_msg (struct msghdr *msg,
00672 ssize_t *nrp, size_t cmsglen) {
00673
00674 ssize_t nr = 0, nnr = 0;
00675 struct iovec iov[1];
00676
00677 iov->iov_base = m_recv_buf;
00678 iov->iov_len = m_recv_buflen ;
00679 msg->msg_iov = iov;
00680 msg->msg_iovlen = 1;
00681
00682 while(true) {
00683
00684 msg->msg_flags = MSGFLAG ;
00685 msg->msg_controllen = cmsglen;
00686
00687 nnr = call_recvmsg(m_socket_id, msg, 0);
00688
00689 if (nnr <= 0) {
00690
00691 *nrp = nr;
00692 return (false);
00693 }
00694
00695 nr += nnr;
00696
00697 if ((msg->msg_flags & MSG_EOR) != 0) {
00698 *nrp = nr;
00699 return (true);
00700 }
00701
00702
00703 if (m_recv_buflen == (size_t)nr) {
00704 m_recv_buflen *= 2;
00705 REALLOC_VAR(m_recv_buf, char*, m_recv_buflen);
00706 }
00707
00708
00709 iov->iov_base = m_recv_buf + nr;
00710 iov->iov_len = m_recv_buflen - nr;
00711 }
00712 }
00713
00714 void C_SocketSCTPWithData::sctp_dispatch_msg (C_TransportEvent *P_event) {
00715
00716 T_pDataRcv L_data ;
00717
00718 ssize_t nr;
00719 struct sctp_sndrcvinfo *sri;
00720 struct msghdr msg[1];
00721 struct cmsghdr *cmsg;
00722 char cbuf[sizeof (*cmsg) + sizeof (*sri)];
00723 struct iovec iov[1];
00724 size_t cmsglen = sizeof (*cmsg) + sizeof (*sri);
00725
00726 m_data_recv = false ;
00727
00728 nr = 0 ;
00729
00730
00731 memset(msg, 0, sizeof (*msg));
00732 msg->msg_control = cbuf;
00733 msg->msg_controllen = cmsglen;
00734 msg->msg_flags = 0;
00735 cmsg = (struct cmsghdr *)cbuf;
00736 sri = (struct sctp_sndrcvinfo *)(cmsg + 1);
00737
00738
00739 while (sctp_recv_msg(msg, &nr, cmsglen)) {
00740
00741
00742 if (msg->msg_flags & MSG_NOTIFICATION) {
00743 sctp_event_handler (P_event);
00744 continue;
00745 }
00746
00747 iov->iov_base = m_recv_buf;
00748 iov->iov_len = nr;
00749 msg->msg_iov = iov;
00750 msg->msg_iovlen = 1;
00751
00752 if (nr) {
00753
00754
00755 if (m_data_recv == false) {
00756 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() RCV " << nr);
00757 P_event->m_type = C_TransportEvent::E_TRANS_RECEIVED ;
00758 P_event->m_channel_id = m_channel_id ;
00759 P_event->m_id = m_socket_id ;
00760 m_data_recv = true ;
00761 }
00762
00763 ALLOC_VAR(L_data, T_pDataRcv, sizeof(T_DataRcv));
00764 L_data->m_size = nr ;
00765 ALLOC_TABLE(L_data->m_data,
00766 unsigned char*,
00767 sizeof(unsigned char*),
00768 nr);
00769 memcpy(L_data->m_data, m_recv_buf, nr);
00770 m_data_queue.push_back(L_data);
00771
00772 } else { break ; }
00773
00774 }
00775
00776 if (nr < 0) {
00777 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() CLOSED");
00778 P_event->m_type = C_TransportEvent::E_TRANS_CLOSED ;
00779 P_event->m_channel_id = m_channel_id ;
00780 P_event->m_id = m_socket_id ;
00781 }
00782 }
00783
00784
00785 C_SocketSCTP* C_SocketSCTPWithData::process_fd_set (fd_set *P_rSet,
00786 fd_set *P_wSet,
00787 C_TransportEvent *P_event) {
00788
00789 SOCKET_DEBUG(0, "C_SocketSCTPWithData::process_fd_set() id=" << m_socket_id);
00790
00791 switch (m_state) {
00792
00793 case E_SOCKET_STATE_READY:
00794 case E_SOCKET_STATE_INPROGESS:
00795
00796 if (FD_ISSET(m_socket_id, P_rSet)) {
00797 sctp_dispatch_msg (P_event) ;
00798 }
00799 break ;
00800
00801 case E_SOCKET_STATE_NOT_READY:
00802 break ;
00803
00804 }
00805
00806 return (NULL);
00807 }
00808
00809 size_t C_SocketSCTPWithData::received_buffer(unsigned char *P_data,
00810 size_t P_size_buf,
00811 struct timeval *P_time) {
00812
00813 size_t L_size = 0 ;
00814 T_DataRcvList::iterator L_it ;
00815 T_pDataRcv L_data ;
00816
00817 SOCKET_DEBUG(0, "C_SocketSCTPWithData::received_buffer() id=" << m_socket_id);
00818
00819 if (!m_data_queue.empty()) {
00820 L_it = m_data_queue.begin();
00821 L_data = *L_it ;
00822 m_data_queue.erase(L_it);
00823 L_size = L_data->m_size ;
00824 SOCKET_DEBUG(0, "C_SocketSCTPWithData::received_buffer() size=" << L_size);
00825 memcpy(P_data, L_data->m_data, L_size);
00826 SOCKET_DEBUG(0, "C_SocketSCTPWithData::received_buffer() L_buf="
00827 << L_data->m_data);
00828 *P_time = L_data->m_time ;
00829 FREE_TABLE(L_data->m_data);
00830 FREE_VAR(L_data) ;
00831 }
00832
00833 SOCKET_DEBUG(0, "C_SocketSCTPWithData::received_buffer() return="
00834 << L_size);
00835 return (L_size);
00836 }
00837