Main Page   Class Hierarchy   Compound List   File List   Compound Members  

C_TransSCTP.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 #include "C_TransSCTP.hpp"
00020 #include "Utils.hpp"
00021 
00022 #include <cerrno>
00023 #include <unistd.h>
00024 
00025 #include <regex.h>
00026 
00027 #include "iostream_t.hpp"
00028 #include "integer_t.hpp"
00029 
00030 #define GEN_ERROR(l,a) iostream_error << a << iostream_endl << iostream_flush ; 
00031 #ifdef DEBUG_MODE
00032 #define GEN_DEBUG(l,a) iostream_error << a << iostream_endl << iostream_flush ; 
00033 #else
00034 #define GEN_DEBUG(l,a) 
00035 #endif
00036 
00037 #define DEFAULT_BUFFER_SIZE 65535
00038 
00039 C_TransSCTP::C_TransSCTP() {
00040   GEN_DEBUG(0, "C_TransSCTP::C_TransSCTP()") ;
00041   m_socket_map.clear () ;
00042   m_max_fd = 0 ;
00043   m_buffer_size = DEFAULT_BUFFER_SIZE ;
00044   sctp_initLibrary();
00045 }
00046 
00047 C_TransSCTP::~C_TransSCTP() {
00048 
00049   T_IpAddrList::iterator L_it ;
00050   T_pIpAddr              L_addr ;
00051   GEN_DEBUG(0, "C_TransSCTP::~C_TransSCTP()") ;
00052   if (!m_ip_addr_list.empty()) {
00053     for(L_it=m_ip_addr_list.begin();
00054         L_it != m_ip_addr_list.end();
00055         L_it++) {
00056       L_addr = *L_it ;
00057       delete_IpAddr(&L_addr);
00058     }
00059     m_ip_addr_list.erase(m_ip_addr_list.begin(), m_ip_addr_list.end());
00060   }
00061   close() ;
00062   m_max_fd = 0 ;
00063 }
00064 
00065 int C_TransSCTP::init (char *P_buf,
00066                        T_logFunction P_logError,
00067                        T_logFunction P_logInfo) {
00068   GEN_DEBUG(1, "C_TransSCTP::init  ("<< P_buf << ")");
00069   return ((analyze_init_string(P_buf) == true) ? 0 : -1);
00070 }
00071 
00072 int C_TransSCTP::config (T_pConfigValueList P_config_param_list) {
00073   GEN_DEBUG(1, "C_TransSCTP::config  ()");
00074   return(0);
00075 }
00076 
00077 int C_TransSCTP::open (int              P_channel_id,
00078                        char            *P_buf, 
00079                        T_pOpenStatus    P_status,
00080                        C_ProtocolFrame *P_protocol) {
00081 
00082   int       L_ret = 0 ;
00083   T_pIpAddr L_openAddr = NULL ;
00084 
00085   GEN_DEBUG(1, "C_TransSCTP::open(protocol=" << P_protocol << ")");
00086 
00087   // check protocol compatibility
00088   if (P_protocol->get_type() != C_ProtocolFrame::E_PROTOCOL_BINARY) {
00089     GEN_ERROR(1, "Protocol not compatible with transport (must be binary)");
00090     return (-1) ;
00091   }
00092 
00093   *P_status = E_OPEN_FAILED ;
00094   L_openAddr = create_IpAddr() ;
00095   
00096   L_ret = (analyze_open_string(P_buf, L_openAddr) == true) ? 
00097     open(P_channel_id, L_openAddr, P_status, (C_ProtocolBinaryFrame*)P_protocol) : -1 ;
00098   
00099   if (L_ret != -1) {
00100     m_ip_addr_list.push_back(L_openAddr) ;
00101   } else {
00102     delete_IpAddr(&L_openAddr);
00103   }
00104   return(L_ret) ;
00105 }
00106 
00107 int C_TransSCTP::set_channel_id (int   P_id,
00108                                  int   P_channel_id) {
00109   int L_ret ;
00110   T_SocketMap::iterator L_it ;
00111   
00112   L_it = m_socket_map.find(T_SocketMap::key_type(P_id));
00113   if (L_it != m_socket_map.end()) {
00114     (L_it->second)->set_channel_id(P_channel_id);
00115     L_ret = 0 ;
00116   } else { 
00117     L_ret = -1 ;
00118   }
00119   return (L_ret);
00120 }
00121 
00122 int C_TransSCTP::pre_select (int             P_n, 
00123                            fd_set         *P_readfds,  
00124                            fd_set         *P_writefds,
00125                            fd_set         *P_exceptfds, 
00126                            struct timeval *P_timeout, 
00127                            int            *P_cnx, 
00128                            size_t          P_nb) {
00129 
00130   T_SocketMap::iterator L_it ;
00131 
00132   for(L_it = m_socket_map.begin();
00133       L_it != m_socket_map.end ();
00134       L_it ++) {
00135     (L_it->second) -> set_fd_set (P_readfds, P_writefds);
00136   }
00137   
00138   return ((m_max_fd > P_n) ? m_max_fd : P_n) ;
00139 }
00140 
00141 int C_TransSCTP::post_select (int                 P_n, 
00142                             fd_set             *P_readfds,  
00143                             fd_set             *P_writefds,
00144                             fd_set             *P_exceptfds, 
00145                             T_pC_TransportEvent P_eventTable,
00146                             size_t             *P_nb) {
00147 
00148   T_SocketMap::iterator L_it ;
00149   int L_n = P_n ;
00150   C_SocketSCTP *L_newSocket, *L_socket ;
00151   C_TransportEvent L_event ;
00152   int L_id ;
00153 
00154   int L_nb_event = 0 ;
00155 
00156   list_t<T_SocketMap::iterator>::iterator L_del_it ;
00157   list_t<C_SocketSCTP*>::iterator         L_ins_it ;
00158   
00159   bool L_max_update = false ;
00160 
00161   GEN_DEBUG(0, "C_TransSCTP::post_select()");
00162 
00163   for (L_it = m_socket_map.begin();
00164        L_it != m_socket_map.end ();
00165        L_it++) {
00166 
00167     if (L_n) {
00168 
00169       L_socket = L_it->second ;
00170       L_event.no_event();
00171       L_newSocket = L_socket->process_fd_set(P_readfds,P_writefds, 
00172                                              &L_event);
00173       switch (L_event.m_type) {
00174             
00175       case C_TransportEvent::E_TRANS_NO_EVENT:
00176         GEN_DEBUG(0, "C_TransSCTP::post_select() E_TRANS_NO_EVENT");
00177         break ;
00178             
00179       case C_TransportEvent::E_TRANS_RECEIVED:
00180         GEN_DEBUG(0, "C_TransSCTP::post_select() E_TRANS_RECEIVED");
00181         P_eventTable[L_nb_event] = L_event ;
00182 
00183         // insert decode process
00184         decode_from_protocol (L_socket);
00185 
00186         L_nb_event++ ;
00187         L_n--;
00188         break ;
00189             
00190       case C_TransportEvent::E_TRANS_CLOSED:
00191         GEN_DEBUG(0, "C_TransSCTP::post_select() E_TRANS_CLOSED");
00192         L_id = (L_socket)->get_id() ;
00193         (L_socket)->_close() ;
00194         m_delete_list.push_back(L_it) ;
00195         DELETE_VAR(L_socket);
00196         if (L_id == m_max_fd) { L_max_update = true ; }
00197         P_eventTable[L_nb_event] = L_event ;
00198         L_nb_event++ ;
00199         L_n-- ;
00200         break ;
00201             
00202       case C_TransportEvent::E_TRANS_CONNECTION:
00203         L_id = L_event.m_id ;
00204         GEN_DEBUG(0, "C_TransSCTP::post_select() E_TRANS_CONNECTION id=" 
00205                   << L_id);
00206         if (L_id > m_max_fd) { L_max_update = true ; }
00207         m_insert_list.push_back(L_newSocket);
00208         P_eventTable[L_nb_event] = L_event ;
00209         L_nb_event++ ;
00210         L_n--;
00211         break ;
00212             
00213       case C_TransportEvent::E_TRANS_OPEN:
00214         P_eventTable[L_nb_event] = L_event ;
00215         L_nb_event++ ;
00216         L_n--;
00217         break ;
00218         
00219       case C_TransportEvent::E_TRANS_OPEN_FAILED:
00220         L_id = (L_socket)->get_id() ;
00221         (L_socket)->_close() ;
00222         m_delete_list.push_back(L_it) ;
00223         DELETE_VAR(L_socket);
00224         if (L_id == m_max_fd) { L_max_update = true ; }
00225         P_eventTable[L_nb_event] = L_event ;
00226         L_nb_event++ ;
00227         L_n--;
00228         break ;
00229         
00230       } // switch
00231     }
00232   }
00233     
00234   if (! m_delete_list.empty() ) {
00235     for(L_del_it = m_delete_list.begin();
00236         L_del_it != m_delete_list.end();
00237         L_del_it++) {
00238       m_socket_map.erase(*L_del_it);
00239     }
00240     m_delete_list.erase(m_delete_list.begin(), m_delete_list.end());
00241   }
00242 
00243   if (! m_insert_list.empty()) {
00244     for(L_ins_it = m_insert_list.begin();
00245         L_ins_it != m_insert_list.end();
00246         L_ins_it++) {
00247       L_newSocket = *L_ins_it ;
00248       L_id = L_newSocket->get_id();
00249       m_socket_map.insert(T_SocketMap::value_type(L_id,L_newSocket));
00250     }
00251     m_insert_list.erase(m_insert_list.begin(), m_insert_list.end());
00252   }
00253 
00254   if (L_max_update == true) {
00255     m_max_fd = (m_socket_map.empty()) ? 
00256       0 : (m_socket_map.rbegin())->first ;
00257     GEN_DEBUG(0, "C_TransSCTP::post_select() max fd [" << m_max_fd << "]");
00258   }
00259 
00260   *P_nb = L_nb_event ;
00261   GEN_DEBUG(0, "C_TransSCTP::post_select() L_nb_event = " << L_nb_event);
00262   GEN_DEBUG(0, "C_TransSCTP::post_select() return  = " << L_n);
00263 
00264   return (L_n);
00265 }
00266 
00267 int C_TransSCTP::send_message (int             P_id,
00268                                C_MessageFrame *P_msg) {
00269 
00270   T_SocketMap::iterator L_it         ;
00271   size_t                L_size = 0   ;
00272   int                   L_ret = -1   ;
00273   C_SocketSCTP         *L_socket     ;
00274   static  unsigned char L_data[1024] ;
00275   
00276   C_ProtocolBinaryFrame *L_protocol ; 
00277   C_ProtocolBinaryFrame::T_MsgError L_error ;
00278 
00279   L_it = m_socket_map.find (T_SocketMap::key_type(P_id));
00280   if (L_it != m_socket_map.end()) {
00281     L_socket = L_it->second ;
00282     L_protocol = L_socket -> get_protocol() ;
00283     L_error = L_protocol->encode_message(P_msg, L_data, &L_size);
00284     L_protocol->log_buffer((char*)"sent", L_data, L_size);
00285     L_ret = send_buffer2(P_id, L_data, L_size) ;
00286   }
00287   return (0) ;
00288 }
00289 
00290 
00291 size_t C_TransSCTP::send_buffer2 (int             P_id, 
00292                                 unsigned char  *P_data, 
00293                                 size_t          P_size) {
00294 
00295   size_t L_size = 0 ;
00296   int    L_rc       ;
00297 
00298   GEN_DEBUG(0, "C_TransSCTP::send_buffer2(" 
00299             << P_id << "," << P_data << "," << P_size << ")");
00300 
00301   GEN_DEBUG(0, "C_TransSCTP::send_buffer() id OK");
00302 
00303   if ((L_rc = call_send(P_id, P_data, P_size, 0) < 0)) {
00304     GEN_ERROR(0, "send failed [" << L_rc << "] [" << strerror(errno) << "]");
00305     switch (errno) {
00306     case EAGAIN:
00307       GEN_ERROR(0, "Flow control not implemented");
00308       break ;
00309     case ECONNRESET:
00310       break ;
00311     default:
00312       GEN_ERROR(0, "process error [" << errno << "] not implemented");
00313       break ;
00314     }
00315   } else {
00316     L_size = P_size ;
00317   }
00318     
00319   GEN_DEBUG(0, "C_TransSCTP::send_buffer2() return " << L_size);
00320   return (L_size);
00321 }
00322 
00323 size_t C_TransSCTP::send_buffer (int             P_id, 
00324                                unsigned char  *P_data, 
00325                                size_t          P_size) {
00326 
00327   T_SocketMap::iterator L_it ;
00328   size_t L_size = 0 ;
00329   int    L_rc       ;
00330 
00331   GEN_DEBUG(0, "C_TransSCTP::send_buffer(" 
00332             << P_id << "," << P_data << "," << P_size << ")");
00333 
00334   L_it = m_socket_map.find (T_SocketMap::key_type(P_id));
00335   if (L_it != m_socket_map.end()) {
00336 
00337     GEN_DEBUG(0, "C_TransSCTP::send_buffer() id OK");
00338     if ((L_rc = call_send(P_id, P_data, P_size, 0) < 0)) {
00339       GEN_ERROR(0, "send failed [" << L_rc << "] [" << strerror(errno) << "]");
00340     } else {
00341       L_size = P_size ;
00342     }
00343   } else {
00344     GEN_ERROR(0, "transport id [" << P_id << "] incorrect");
00345   }
00346 
00347   GEN_DEBUG(0, "C_TransSCTP::send_buffer() return " << L_size);
00348   return (L_size);
00349 }
00350 
00351 size_t C_TransSCTP::received_buffer (int            P_id, 
00352                                    unsigned char *P_data, 
00353                                    size_t         P_size_buf) {
00354 
00355   T_SocketMap::iterator L_it ;
00356   size_t                L_ret = 0 ;
00357 
00358   GEN_DEBUG(0, "C_TransSCTP::received_buffer(" << P_id << ")");
00359   L_it = m_socket_map.find(T_SocketMap::key_type(P_id));
00360   if (L_it != m_socket_map.end()) {
00361     // L_ret = (L_it->second) -> received_buffer (P_data, P_size_buf); CONFIRM ?
00362   } else {
00363     GEN_ERROR(0, "transport id [" << P_id << "] incorrect");
00364   }
00365   return (L_ret);
00366 }
00367 
00368 T_SelectDef C_TransSCTP::select_definition() {
00369   GEN_DEBUG(0, "C_TransSCTP::select_definition () ");
00370   return (&call_select);
00371 }
00372   
00373 int C_TransSCTP::close () {
00374 
00375   GEN_DEBUG(0, "C_TransSCTP::close ()");
00376   T_SocketMap::iterator L_it ;
00377   C_SocketSCTP *L_socket ;
00378   
00379   if (!m_socket_map.empty()) {
00380     for (L_it = m_socket_map.begin();
00381          L_it != m_socket_map.end ();
00382          L_it++) {
00383       L_socket = L_it->second ;
00384       L_socket -> _close();
00385       DELETE_VAR(L_socket);
00386     }
00387     m_socket_map.erase(m_socket_map.begin(), m_socket_map.end());
00388   }
00389   return (0);
00390 }
00391 
00392 int C_TransSCTP::close (int P_id) {
00393 
00394   T_SocketMap::iterator L_it ;
00395   C_SocketSCTP *L_socket ;
00396   int       L_ret = 0 ;
00397 
00398   GEN_DEBUG(0, "C_TransSCTP::close (" << P_id << ")");
00399   if (!m_socket_map.empty()) {
00400     L_it = m_socket_map.find (T_SocketMap::key_type(P_id));
00401     if (L_it != m_socket_map.end()) {
00402       L_socket = L_it->second ;
00403       L_socket -> _close();
00404       DELETE_VAR(L_socket);
00405       m_socket_map.erase(L_it);
00406     } else {
00407       L_ret = -1 ; 
00408     }
00409   } else {
00410     L_ret = -1 ;
00411   }
00412 
00413   return (L_ret);
00414 }
00415 
00416 // Internal methods
00417 
00418 int C_TransSCTP::open (int              P_channel_id, 
00419                        T_pIpAddr        P_Addr,
00420                        T_pOpenStatus    P_status,
00421                        C_ProtocolBinaryFrame *P_protocol) {
00422   
00423   // Temporary for source/destination address
00424   //  char              *L_ptr ;
00425   char              *L_server_name   ;
00426   //  int                L_port ;
00427   //  int                L_server_port ;
00428   int                L_id = -1 ;
00429   int                L_rc ;
00430   C_SocketSCTP          *L_socket_created = NULL ;
00431   //  T_IpAddr           L_addr ;
00432 
00433   GEN_DEBUG(1, "C_TransSCTP::open ()");
00434 
00435   L_server_name = NULL ;
00436 
00437   if (P_Addr->m_open != NULL) {
00438     extract_ip_addr(P_Addr);
00439     resolve_addr(P_Addr);
00440   }
00441 
00442   switch (P_Addr->m_umode) {
00443   case E_IP_USAGE_MODE_SERVER: {
00444     C_SocketSCTPListen *L_Socket ;
00445     NEW_VAR(L_Socket, C_SocketSCTPListen(m_trans_type, P_Addr, P_channel_id));
00446     L_rc = L_Socket->_open(m_buffer_size, P_protocol) ; 
00447     if (L_rc == 0) {
00448       L_socket_created = L_Socket ;
00449       *P_status = E_OPEN_OK ;
00450     } else {
00451       DELETE_VAR(L_Socket) ;
00452       *P_status = E_OPEN_FAILED ;
00453     }
00454   }
00455     break ;
00456     
00457   case E_IP_USAGE_MODE_CLIENT: {
00458     C_SocketSCTPClient *L_Socket ;
00459     NEW_VAR(L_Socket, C_SocketSCTPClient(m_trans_type, P_Addr, P_channel_id));
00460     L_rc = L_Socket->_open(P_status, m_buffer_size, P_protocol) ;
00461     if (L_rc == 0) {
00462       L_socket_created = L_Socket ;
00463     } else {
00464       DELETE_VAR(L_Socket) ;
00465       *P_status = E_OPEN_FAILED ;
00466     }
00467   }
00468 
00469     break ;
00470 
00471   case E_IP_USAGE_MODE_UNKNOWN:
00472 
00473     GEN_ERROR(1, "OPEN failed: Unsupported mode");
00474     *P_status = E_OPEN_FAILED ;
00475     break ;
00476   }
00477   
00478   if (L_socket_created != NULL) {
00479     L_id = L_socket_created -> get_id () ;
00480     m_socket_map.insert (T_SocketMap::value_type(L_id,L_socket_created));
00481     if (L_id > m_max_fd) { m_max_fd = L_id;  } ;
00482   }
00483 
00484   FREE_VAR(L_server_name);
00485   
00486   return (L_id);
00487 }
00488 
00489 bool C_TransSCTP::analyze_init_string(char *P_buf) {
00490 
00491   bool             L_ret = false ;
00492   char             L_type [255] ;
00493   char            *L_ptr ;
00494 
00495   GEN_DEBUG(1, "C_TransSCTP::analyze_init_string  ("<< P_buf << ")");
00496   L_ptr = strstr(P_buf,"type=") ;
00497   if (L_ptr != NULL) {
00498     sscanf(L_ptr, "type=%[^;]*s", L_type);
00499     if (!strcmp(L_type,"tcp")) {
00500       m_trans_type = E_SOCKET_TCP_MODE ;
00501       L_ret = true ;
00502     } else if (!strcmp(L_type,"udp")) {
00503       m_trans_type = E_SOCKET_UDP_MODE ;
00504       L_ret = true ;
00505     }
00506     GEN_DEBUG(1, "C_TransSCTP::analyze_init_string() type [" << L_type << "]");
00507   }
00508   return (L_ret);
00509   
00510 }
00511 
00512 bool C_TransSCTP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
00513 
00514   char            L_tmp  [255] ;
00515   char           *L_buf, *L_ptr ;
00516 
00517   GEN_DEBUG(1, "C_TransSCTP::analyze_open_string (args=" << P_buf << ")");
00518 
00519   L_buf = P_buf ;
00520   L_ptr = strstr(L_buf, "mode=");
00521   if (L_ptr != NULL) {
00522     sscanf(L_ptr+5, "%[^;]*s", L_tmp);
00523     GEN_DEBUG(1, "m [" << L_tmp << "]");
00524     if (!strcmp(L_tmp,"server")) {
00525       P_addr->m_umode = E_IP_USAGE_MODE_SERVER ;
00526     } else if (!strcmp(L_tmp,"client")) {
00527       P_addr->m_umode = E_IP_USAGE_MODE_CLIENT ;
00528     }
00529   }
00530   L_buf = P_buf ;
00531   L_ptr = strstr(L_buf, "source=");
00532   if (L_ptr != NULL) {
00533     sscanf(L_ptr+7, "%[^;]*s", L_tmp);
00534     GEN_DEBUG(1, "C_TransSCTP::analyze_open_string() s [" << L_tmp << "]");
00535     if (strlen(L_tmp)>0) {
00536       ALLOC_TABLE(P_addr->m_open,
00537                   char*,sizeof(char),
00538                   strlen(L_tmp)+1);
00539       strcpy(P_addr->m_open, L_tmp);
00540     } 
00541   }
00542   L_buf = P_buf ;
00543   L_ptr = strstr(L_buf, "dest=");
00544   if (L_ptr != NULL) {
00545     sscanf(L_ptr+5, "%[^;]*s", L_tmp);
00546     GEN_DEBUG(1, "C_TransSCTP::analyze_open_string() d [" << L_tmp << "]");
00547     if (strlen(L_tmp)>0) {
00548       ALLOC_TABLE(P_addr->m_open,
00549                   char*,sizeof(char),
00550                   strlen(L_tmp)+1);
00551       strcpy(P_addr->m_open, L_tmp);
00552     }
00553   }
00554 
00555   L_buf = P_buf ;
00556   L_ptr = strstr(L_buf, "buffer=");
00557   if (L_ptr != NULL) {
00558     sscanf(L_ptr+7, "%[^;]*s", L_tmp);
00559     GEN_DEBUG(1, "C_TransSCTP::analyze_open_string() buffer size [" 
00560               << L_tmp << "]");
00561     if (strlen(L_tmp)>0) {
00562       char *L_end_ptr ;
00563       unsigned long L_value ;
00564       L_value = strtoul_f (L_tmp, &L_end_ptr, 10);
00565       if (L_end_ptr[0] == '\0') { // good format
00566         m_buffer_size = L_value ;
00567         P_addr->m_buffer_size = L_value ;
00568       }
00569     }
00570   }
00571 
00572   return (true) ;
00573 }
00574 
00575 int C_TransSCTP::extract_ip_addr(T_pIpAddr P_pIpAddr) {
00576   
00577   char      *L_search = NULL ;
00578 
00579   regex_t    L_regExpr ;
00580   regmatch_t L_pmatch ;
00581   int        L_status ;
00582 
00583   char       L_buffer[1024] ;
00584   size_t     L_matchSize ;
00585 
00586   GEN_DEBUG(0, "C_TransSCTP::extract_ip_addr()");
00587 
00588   if (P_pIpAddr == NULL) { return (-1) ; }
00589   if (P_pIpAddr->m_open == NULL) { return (0) ; }
00590 
00591   L_search = P_pIpAddr->m_open ;
00592   P_pIpAddr -> m_value = NULL ;
00593   P_pIpAddr -> m_port = -1 ;
00594   memset(&(P_pIpAddr->m_addr), 0, sizeof(T_SockAddrStorage));
00595 
00596   // skip blank 
00597   L_status = regcomp (&L_regExpr, "^[:blank:]*\\[", REG_EXTENDED) ;
00598   if (L_status != 0) {
00599     regerror(L_status, &L_regExpr, L_buffer, 1024);
00600     regfree (&L_regExpr) ;
00601     GEN_ERROR(0, "regcomp error: [" << L_buffer << "]");
00602     return (-1);
00603   }
00604   
00605   L_status = regexec (&L_regExpr, L_search, 1, &L_pmatch, 0) ;
00606   regfree (&L_regExpr) ;
00607 
00608   if (L_status == 0) { // IP V6
00609 
00610     L_search += L_pmatch.rm_eo ;
00611 
00612     // find end of address
00613     L_status = regcomp(&L_regExpr, "[^]]*", REG_EXTENDED) ;
00614     if (L_status != 0) {
00615       regerror(L_status, &L_regExpr, L_buffer, 1024);
00616       regfree (&L_regExpr) ;
00617       GEN_ERROR(0, "regcomp error: [" << L_buffer << "]");
00618       return (-1);
00619     }
00620 
00621     L_status = regexec (&L_regExpr, L_search, 1, &L_pmatch, 0) ;
00622     regfree (&L_regExpr) ;
00623     if (L_status == 0) { // end of IP addr found
00624 
00625       L_matchSize = L_pmatch.rm_eo - L_pmatch.rm_so ;
00626       if (L_matchSize) { memcpy(L_buffer, L_search, L_matchSize); }
00627       L_buffer[L_matchSize] = 0 ;
00628       L_search += L_matchSize ;
00629       L_search = strstr(L_search, ":");
00630 
00631       GEN_DEBUG(1, "C_TransSCTP::extract_ip_addr() IPV6 addr [" << L_buffer << "]");
00632       
00633     } else {
00634       GEN_ERROR(0, "regexec error character [" << ']' << "] not found" );
00635       return (-1);
00636     }
00637 
00638   } else { // IP V4 or hostname
00639 
00640     
00641     L_search = strstr(P_pIpAddr->m_open, ":") ;
00642 
00643     L_matchSize = (L_search != NULL) 
00644       ? (L_search - (P_pIpAddr->m_open)) : strlen(P_pIpAddr->m_open) ;
00645     if (L_matchSize) { memcpy(L_buffer, P_pIpAddr->m_open, L_matchSize) ; }
00646     L_buffer[L_matchSize] = 0 ;
00647 
00648       
00649     GEN_DEBUG(0, "C_TransSCTP::extract_ip_addr() IPV4 addr or hostname = [" 
00650               << L_buffer << "]");
00651   }
00652 
00653   if (strlen(L_buffer) != 0) {
00654     ALLOC_TABLE(P_pIpAddr -> m_value, char*, 
00655                 sizeof(char), strlen(L_buffer)+1) ;
00656     strcpy(P_pIpAddr->m_value, L_buffer);
00657   }
00658 
00659   if (L_search != NULL) {
00660     char *L_end_ptr = NULL ;
00661     P_pIpAddr -> m_port = (long)strtoul_f(L_search+1, &L_end_ptr, 10);
00662     if (L_end_ptr[0] != '\0') { 
00663       P_pIpAddr->m_port = -1 ;
00664       GEN_DEBUG (0, "C_TransSCTP::extract_ip_addr() port not defined");
00665     }
00666   } else {
00667     GEN_DEBUG (0, "C_TransSCTP::extract_ip_addr() port not defined");
00668   }
00669 
00670   GEN_DEBUG(1, "C_TransSCTP::extract_ip_addr() Port [" << P_pIpAddr->m_port << "]");
00671 
00672 #ifdef DEBUG_MODE
00673   {
00674     const char *L_novalue = "no value" ;
00675     char *L_value = (P_pIpAddr->m_value == NULL) ?
00676       (char*)L_novalue : P_pIpAddr->m_value ;
00677     GEN_DEBUG(1, "C_TransSCTP::extract_ip_addr() Addr value [" 
00678               << L_value << "]") ;
00679   }
00680 #endif
00681 
00682   return (0);
00683 }
00684 
00685 int C_TransSCTP::resolve_addr(T_pIpAddr P_pIpAddr) {
00686 
00687   char              *L_host              = P_pIpAddr->m_value ;
00688   long               L_port              = P_pIpAddr->m_port  ;
00689   T_SockAddrStorage *L_resolved_sockaddr = &P_pIpAddr->m_addr ;
00690   char               L_local_host[255]                        ;
00691 
00692 #ifndef USE_IPV4_ONLY  
00693   struct addrinfo   L_hints      ;
00694   struct addrinfo  *L_local_addr ;
00695 #else
00696   struct hostent   *L_local_addr ;
00697 #endif
00698 
00699 #ifdef DEBUG_MODE
00700 
00701   const char *L_cNoHost = "none" ;
00702   char *L_hostDebug = (L_host == NULL) ? (char*)L_cNoHost : L_host ;
00703 
00704   GEN_DEBUG(1, "C_TransSCTP::resolve_addr() [" 
00705             << L_hostDebug
00706             << "]:[" << L_port << "]");
00707 #endif
00708 
00709 #ifndef USE_IPV4_ONLY
00710   memset((char*)&L_hints, 0, sizeof(L_hints));
00711   L_hints.ai_flags  = AI_PASSIVE;
00712   L_hints.ai_family = PF_UNSPEC;
00713 #endif
00714 
00715   if (L_host == NULL) {
00716     if (gethostname(L_local_host, 255)) {
00717       GEN_ERROR(1, "Unable to get local IP address");
00718       return(-1);
00719     } else {
00720       ALLOC_TABLE(L_host, char*, sizeof(char),
00721                   strlen(L_local_host)+1);
00722       strcpy(L_host, L_local_host) ;
00723       P_pIpAddr->m_value = L_host  ;
00724     }
00725   }
00726   memset(L_resolved_sockaddr, 0, sizeof(T_SockAddrStorage));
00727 
00728 #ifndef USE_IPV4_ONLY
00729   if (getaddrinfo(L_host,
00730                   NULL,
00731                   &L_hints,
00732                   &L_local_addr) != 0) {
00733     GEN_ERROR(1, "Unknown host [" << L_host << "]");
00734     return (-1);
00735   }
00736 
00737   L_resolved_sockaddr->SOCKADDR_FAMILY = L_local_addr->ai_addr->sa_family;
00738   memcpy(L_resolved_sockaddr,
00739          L_local_addr->ai_addr,
00740          SOCKADDR_IN_SIZE
00741          (RICAST(T_SockAddrStorage *,L_local_addr->ai_addr)));
00742 #else
00743   L_local_addr = gethostbyname(L_host);
00744   if (L_local_addr != NULL) {
00745     L_resolved_sockaddr->SOCKADDR_FAMILY = L_local_addr->h_addrtype;
00746     memcpy((void*)L_resolved_sockaddr->sin_addr.s_addr,
00747            L_local_addr->h_addr_list[0],
00748            L_local_addr->h_length);
00749   } else {
00750     GEN_ERROR(1, "Unknown host [" << L_host << "]");
00751     return (-1);
00752   }
00753 #endif
00754 
00755   switch (L_resolved_sockaddr->SOCKADDR_FAMILY) {
00756   case AF_INET:
00757     (RICAST(struct sockaddr_in *, L_resolved_sockaddr))->sin_port =
00758       htons((short)L_port);
00759     break ;
00760 #ifndef USE_IPV4_ONLY
00761   case AF_INET6:
00762     (RICAST(struct sockaddr_in6 *, L_resolved_sockaddr))->sin6_port =
00763       htons((short)L_port);
00764     break ;
00765 #endif
00766   default:
00767     GEN_ERROR(1, "Unsupported network");
00768     return(-1);
00769   }
00770   if (inet_addr((char**)&(P_pIpAddr->m_ip), L_resolved_sockaddr) == -1) {
00771     GEN_ERROR(1, "Address not supported");
00772   }
00773 
00774   GEN_DEBUG(0, "C_TransSCTP::inet_addr() inet_addr [" << P_pIpAddr->m_ip << "]");
00775 
00776   return(0);
00777 }
00778 
00779 int C_TransSCTP::inet_addr(char **P_Addr, T_SockAddrStorage * P_AddrS) {
00780 
00781 #ifndef USE_IPV4_ONLY
00782   char * L_ipAddr = NULL;
00783 
00784   GEN_DEBUG(0, "C_TransSCTP::inet_addr()");
00785 
00786   ALLOC_TABLE(L_ipAddr, char*, sizeof(char), 1024);
00787 
00788   if (getnameinfo(RICAST(struct sockaddr *, P_AddrS),
00789                   sizeof(struct sockaddr_storage),
00790                   L_ipAddr,
00791                   1024,
00792                   NULL,
00793                   0,
00794                   NI_NUMERICHOST) != 0) {
00795     FREE_TABLE(L_ipAddr);
00796     return(-1);
00797   }
00798 
00799   *P_Addr = L_ipAddr ;
00800 #endif 
00801   return (0) ;
00802   
00803 }
00804 
00805 void C_TransSCTP::decode_from_protocol (C_SocketSCTP *P_socket) {
00806 
00807   // previous data remaining buffer
00808   size_t                            L_data_size, L_tmp_size ;
00809   static unsigned char              L_data [4096] ;
00810   size_t                            L_buf_size = 4096 ;
00811   unsigned char                    *L_session_buf, *L_current_data ;
00812   C_pSCTPDataDecode                 L_decode = P_socket->get_decode() ;
00813   C_ProtocolBinaryFrame            *L_protocol = P_socket->get_protocol() ;
00814   T_pRcvMsgCtxtList                 L_msg_list = P_socket->get_list() ;
00815   T_ReceiveMsgContext               L_msg_ctxt ;
00816   
00817   C_MessageFrame                   *L_decoded_msg ;
00818   C_ProtocolBinaryFrame::T_MsgError L_decode_result        ;
00819   size_t                            L_ret ;
00820   
00821   GEN_DEBUG(0, "C_TransSCTP::decode_from_protocol() start");
00822 
00823   L_msg_ctxt.m_channel = P_socket->get_channel_id() ;
00824   L_msg_ctxt.m_response = P_socket->get_id();
00825 
00826   while ((L_data_size 
00827           = P_socket->received_buffer(L_data, 
00828                                       L_buf_size, 
00829                                       &L_msg_ctxt.m_time)) != 0) {
00830 
00831     L_protocol->log_buffer((char*)"received", L_data, L_data_size);
00832 
00833     L_session_buf = L_decode -> get_buffer(L_data, &L_data_size);
00834 
00835     L_current_data = L_session_buf ;
00836     L_tmp_size = L_data_size ;
00837     L_ret = L_data_size ;
00838     
00839     if (L_tmp_size) {
00840 
00841       do {
00842 
00843         // start decode engine
00844         L_decoded_msg 
00845           = L_protocol->decode_message (L_current_data, 
00846                                         &L_ret, 
00847                                         &L_decode_result) ;
00848         
00849         switch (L_decode_result) {
00850 
00851         case C_ProtocolBinaryFrame::E_MSG_OK:
00852           // Store new message received
00853           // for the call controller
00854 
00855           L_msg_ctxt.m_msg = L_decoded_msg ;
00856           L_msg_list->push_back(L_msg_ctxt);
00857           
00858           // prepare for next message
00859           L_tmp_size = L_data_size - L_ret ;
00860           if (L_ret != 0) { // not the last of the buffer
00861             L_current_data += L_tmp_size ;
00862             L_data_size -= L_tmp_size ;
00863           }
00864           break ;
00865 
00866         case C_ProtocolBinaryFrame::E_MSG_ERROR_DECODING_SIZE_LESS:
00867           // segmentation
00868           // => put L_current_data and L_data_size in 
00869           // => remaining data_buffer
00870 
00871           // save buffer for next receive
00872           if (L_decode->set_buffer (L_current_data, 
00873                                     L_data_size) != 0) {
00874             L_decode->reset_buffer() ;
00875           } 
00876           L_ret = 0 ;
00877           break ;
00878         default:
00879           // TO BE DONE : 
00880           // more complex synchronization algorithm !!!!!
00881           GEN_ERROR(E_GEN_FATAL_ERROR, 
00882                     "Unrecognized message received") ;
00883           L_decode->reset_buffer() ;
00884           L_data_size = 0 ;
00885           L_ret = 0 ;
00886           break ;
00887         }
00888       
00889       } while (L_ret != 0) ;
00890 
00891     }
00892 
00893   }
00894 
00895   GEN_DEBUG(0, "C_TransSCTP::decode_from_protocol() end");
00896 }
00897 
00898 bool C_TransSCTP::get_message (int P_id, T_pReceiveMsgContext P_ctxt) {
00899 
00900   T_SocketMap::iterator  L_it          ;
00901   bool                   L_ret = false ;
00902   T_pRcvMsgCtxtList      L_list        ;
00903 
00904   GEN_DEBUG(0, "C_TransSCTP::get_message(" << P_id << ")");
00905 
00906   L_it = m_socket_map.find(T_SocketMap::key_type(P_id));
00907   if (L_it != m_socket_map.end()) {
00908     L_list = (L_it->second)->get_list() ;
00909     if (!L_list->empty()) {
00910       *P_ctxt = *L_list->begin() ;
00911       L_ret = true ;
00912       L_list->erase(L_list->begin()) ;
00913     }
00914   } else {
00915     GEN_ERROR(0, "transport id [" << P_id << "] incorrect");
00916   }
00917 
00918   GEN_DEBUG(0, "C_TransSCTP::get_message() end with " << L_ret);
00919   return (L_ret);
00920 }
00921 
00922 // External interface
00923 
00924 T_pTransport create_cipio_instance () {
00925   T_pC_TransSCTP L_inst ;
00926   NEW_VAR(L_inst, C_TransSCTP());
00927   return (L_inst);
00928 }
00929 
00930 void delete_cipio_instance (T_ppTransport P_inst) {
00931   if (P_inst != NULL) {
00932     T_pC_TransSCTP L_inst = (T_pC_TransSCTP) *P_inst ;
00933     DELETE_VAR(L_inst);
00934     *P_inst = NULL ;
00935   }
00936 }
00937 
00938 // end of file

Generated on Wed Mar 7 14:44:59 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002