00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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 }
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
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
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
00424
00425 char *L_server_name ;
00426
00427
00428 int L_id = -1 ;
00429 int L_rc ;
00430 C_SocketSCTP *L_socket_created = NULL ;
00431
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') {
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
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) {
00609
00610 L_search += L_pmatch.rm_eo ;
00611
00612
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) {
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 {
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
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
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
00853
00854
00855 L_msg_ctxt.m_msg = L_decoded_msg ;
00856 L_msg_list->push_back(L_msg_ctxt);
00857
00858
00859 L_tmp_size = L_data_size - L_ret ;
00860 if (L_ret != 0) {
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
00868
00869
00870
00871
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
00880
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
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