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