diff --git a/docker/ubuntu-16.04/Dockerfile b/docker/ubuntu-16.04/Dockerfile index 18d5448..5665e1c 100644 --- a/docker/ubuntu-16.04/Dockerfile +++ b/docker/ubuntu-16.04/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:16.04 as builder RUN apt update \ - && apt install -y build-essential curl git libglib2.0-dev ksh bison flex vim + && apt install -y build-essential curl git libglib2.0-dev ksh bison flex vim libsctp-dev RUN mkdir -p ~/opt/src \ && cd ~/opt/src \ @@ -24,7 +24,7 @@ RUN tar czf /root/bin.tgz ~/opt/src/seagull/seagull/trunk/src/bin/* \ FROM ubuntu:16.04 as distro RUN apt update \ - && apt install -y ksh locales \ + && apt install -y ksh locales libsctp1 \ && apt upgrade -y \ && locale-gen en_US.UTF-8 \ && dpkg-reconfigure --frontend noninteractive locales \ diff --git a/docker/ubuntu-18.04/Dockerfile b/docker/ubuntu-18.04/Dockerfile index 2bba1cb..7953b6f 100644 --- a/docker/ubuntu-18.04/Dockerfile +++ b/docker/ubuntu-18.04/Dockerfile @@ -24,7 +24,7 @@ RUN tar czf /root/bin.tgz ~/opt/src/seagull/seagull/trunk/src/bin/* \ FROM ubuntu:18.04 as distro RUN apt update \ - && apt install -y ksh locales \ + && apt install -y ksh locales libsctp1 \ && apt upgrade -y \ && locale-gen en_US.UTF-8 \ && dpkg-reconfigure --frontend noninteractive locales \ diff --git a/seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp b/seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp index 8053236..2c87153 100755 --- a/seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp +++ b/seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp @@ -23,6 +23,10 @@ #include "C_Socket.hpp" #include "C_SocketSCTP.hpp" +#include +#include +#include + #define MSGFLAG 0 #define MAX_OUTGOING 128 @@ -100,7 +104,6 @@ void C_SocketSCTPListen::set_properties() { SOCKET_ERROR(1, "Unable to set SCTP_EVENTS option"); } - // SCTP END } // size of recv buf @@ -182,10 +185,26 @@ int C_SocketSCTPListen::_open (size_t P_buffer_size, // set_properties() ; /* bind the socket to the newly formed address */ - L_rc = bind(m_socket_id, - (sockaddr *)(void *)&(m_source_addr_info->m_addr), - SOCKADDR_IN_SIZE(&(m_source_addr_info->m_addr))); - /* check there was no error */ + + struct sockaddr_storage *bind_addr = NULL; + unsigned int cc = 0; + SOCKET_DEBUG(0, "bind1 start"); + unsigned int bind_addr_count = m_source_addr_info->m_addrs_src.size(); + for (unsigned int i = 0; i < bind_addr_count; i++) { + sockaddr_in *so = (sockaddr_in *)(m_source_addr_info->m_addrs_src[i]->ai_addr); + size_t addrlen = m_source_addr_info->m_addrs_src[i]->ai_addrlen; + SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr) + << ":" << ntohs(so->sin_port)); + bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen); + memcpy((char*)bind_addr + cc, so, addrlen); + cc += addrlen; + } + + SOCKET_DEBUG(0, "binding stop"); + L_rc = sctp_bindx(m_socket_id, + (struct sockaddr*)bind_addr, + bind_addr_count, SCTP_BINDX_ADD_ADDR); + /* check there was no error */ if (L_rc) { SOCKET_ERROR(1, "bind [" << strerror(errno) << "]"); } else { @@ -809,9 +828,22 @@ int C_SocketSCTPServer::_open_udp (size_t P_buffer_size, m_buffer_size = P_buffer_size ; /* bind the socket to the newly formed address */ - L_rc = bind(m_socket_id, - (sockaddr *)(void *)&(m_source_udp_addr_info->m_addr), - SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr))); + struct sockaddr_storage *bind_addr = NULL; + unsigned int cc = 0; + unsigned int bind_addr_count = m_source_udp_addr_info->m_addrs_src.size(); + for (unsigned int i = 0; i < bind_addr_count; i++) { + sockaddr_in *so = (sockaddr_in *)(m_source_udp_addr_info->m_addrs_src[i]->ai_addr); + size_t addrlen = m_source_udp_addr_info->m_addrs_src[i]->ai_addrlen; + SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr) + << ":" << ntohs(so->sin_port)); + bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen); + memcpy((char*)bind_addr + cc, so, addrlen); + cc += addrlen; + } + + L_rc = sctp_bindx(m_socket_id, + (struct sockaddr*)bind_addr, + bind_addr_count, SCTP_BINDX_ADD_ADDR); /* check there was no error */ if (L_rc) { SOCKET_ERROR(1, "bind [" << strerror(errno) << "]"); @@ -894,13 +926,45 @@ int C_SocketSCTPClient::_open(T_pOpenStatus P_status, if (L_rc == 0) { if (m_type == E_SOCKET_TCP_MODE) { + // SCTP MULTIHOMING CLIENT BINDING + struct sockaddr_storage *bind_addr = NULL; + unsigned int cc = 0; + unsigned int bind_addr_count = m_remote_addr_info->m_addrs_src.size(); + for (unsigned int i = 0; i < bind_addr_count; i++) { + sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_src[i]->ai_addr); + size_t addrlen = m_remote_addr_info->m_addrs_src[i]->ai_addrlen; + SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr) + << ":" << ntohs(so->sin_port)); + bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen); + memcpy((char*)bind_addr + cc, so, addrlen); + cc += addrlen; + } + + if(bind_addr_count > 0) { + if(sctp_bindx(m_socket_id, + (struct sockaddr*)bind_addr, + bind_addr_count, SCTP_BINDX_ADD_ADDR)) { + SOCKET_ERROR(1, "error bind client [" << strerror(errno) << "]"); + } + } - - L_rc = connect (m_socket_id, - (struct sockaddr*)(void*)&(m_remote_addr_info->m_addr), - SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ; - + struct sockaddr_storage *connect_addr = NULL; + cc = 0; + unsigned int connect_addr_count = m_remote_addr_info->m_addrs_dst.size(); + for (unsigned int i = 0; i < connect_addr_count; i++) { + sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_dst[i]->ai_addr); + size_t addrlen = m_remote_addr_info->m_addrs_dst[i]->ai_addrlen; + SOCKET_DEBUG(0, "connect to " << inet_ntoa(so->sin_addr) + << ":" << ntohs(so->sin_port)); + connect_addr = (sockaddr_storage*)realloc(connect_addr, cc + addrlen); + memcpy((char*)connect_addr + cc, so, addrlen); + cc += addrlen; + } + + L_rc = sctp_connectx(m_socket_id, + (struct sockaddr*)connect_addr, + connect_addr_count, 0); if (L_rc) { if (errno != EINPROGRESS) { SOCKET_ERROR(1, "connect failed [" @@ -919,9 +983,23 @@ int C_SocketSCTPClient::_open(T_pOpenStatus P_status, *P_status = E_OPEN_OK ; } } else { - L_rc = bind(m_socket_id, - (sockaddr *)(void *)&(m_remote_addr_info->m_addr_src), - SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src))); + struct sockaddr_storage *bind_addr = NULL; + unsigned int cc = 0; + SOCKET_DEBUG(0, "bind start"); + unsigned int bind_addr_count = m_remote_addr_info->m_addrs_src.size(); + for (unsigned int i = 0; i < bind_addr_count; i++) { + sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_src[i]->ai_addr); + size_t addrlen = m_remote_addr_info->m_addrs_src[i]->ai_addrlen; + SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr) + << ":" << ntohs(so->sin_port)); + bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen); + memcpy((char*)bind_addr + cc, so, addrlen); + cc += addrlen; + } + + L_rc = sctp_bindx(m_socket_id, + (struct sockaddr*)bind_addr, + bind_addr_count, SCTP_BINDX_ADD_ADDR); if (L_rc) { SOCKET_ERROR(1, "bind [" << strerror(errno) << "]"); diff --git a/seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp b/seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp index 76a6a16..ff5879a 100755 --- a/seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp +++ b/seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp @@ -38,7 +38,7 @@ int C_TransSCTP::config (T_pConfigValueList P_config_param_list) { - GEN_DEBUG(1, "C_TransIP::config ()"); + GEN_DEBUG(1, "C_TransSCTP::config ()"); m_logInfo = NULL ; m_logError = NULL ; @@ -85,7 +85,7 @@ C_Socket* C_TransSCTP::open (int P_channel_id, - GEN_DEBUG(1, "C_TransIPTLS::open ()"); + GEN_DEBUG(1, "C_TransSCTP::open ()"); switch (P_Addr->m_umode) { case E_IP_USAGE_MODE_SERVER: { diff --git a/seagull/trunk/src/library-trans-ip/C_TransIP.cpp b/seagull/trunk/src/library-trans-ip/C_TransIP.cpp index 6fb026c..c75c869 100644 --- a/seagull/trunk/src/library-trans-ip/C_TransIP.cpp +++ b/seagull/trunk/src/library-trans-ip/C_TransIP.cpp @@ -21,7 +21,11 @@ #include "Utils.hpp" #include +#include #include +#include +#include +#include #include @@ -743,7 +747,7 @@ bool C_TransIP::analyze_init_string(char *P_buf) { bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) { - char L_tmp [255] ; + char L_tmp [255], L_tmp_port[255]; char L_tmp_lag [255] ; char *L_buf, *L_ptr ; @@ -775,10 +779,46 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) { char*,sizeof(char), strlen(L_tmp)+1); strcpy(P_addr->m_open_src, L_tmp); - } + + L_ptr = L_buf; + while(1) { + L_ptr = strstr(L_ptr, "source="); + if (L_ptr != NULL) { + struct addrinfo *addr; + struct addrinfo L_hints; + memset((char*)&L_hints, 0, sizeof(L_hints)); + L_hints.ai_flags = AI_PASSIVE; + L_hints.ai_family = PF_UNSPEC; + + sscanf(L_ptr+7, "%[^;]*s", L_tmp); + + L_tmp_port[0] = '\0'; + char* delem = strstr(L_tmp, ":"); + if(delem != NULL) { + strncpy(L_tmp_port, delem + 1, 254); + (*delem) = '\0'; + } + + GEN_DEBUG(1, "source [" << L_tmp << ":" << L_tmp_port << "]"); + if (getaddrinfo(L_tmp, + L_tmp_port, + &L_hints, + &addr) != 0) { + GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]"); + } else { + GEN_DEBUG(1, "add src to m_addrs_dst"); + P_addr->m_addrs_src.push_back(addr); + } + L_ptr = L_ptr + 7; + } else { + break; + } + } + } } if (m_active) { + GEN_DEBUG(1, "C_TransIP::m_active: true"); L_buf = P_buf ; L_ptr = strstr(L_buf, "dest="); if (L_ptr != NULL) { @@ -790,8 +830,43 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) { strlen(L_tmp)+1); strcpy(P_addr->m_open, L_tmp); } + + L_ptr = L_buf; + while(1) { + L_ptr = strstr(L_ptr, "dest="); + if (L_ptr != NULL) { + struct addrinfo *addr; + struct addrinfo L_hints; + memset((char*)&L_hints, 0, sizeof(L_hints)); + L_hints.ai_flags = AI_PASSIVE; + L_hints.ai_family = PF_UNSPEC; + + sscanf(L_ptr + 5, "%[^;]*s", L_tmp); + + L_tmp_port[0] = '\0'; + char* delem = strstr(L_tmp, ":"); + if(delem != NULL) { + strncpy(L_tmp_port, delem + 1, 254); + (*delem) = '\0'; + } + GEN_DEBUG(1, "dst a[" << L_tmp << ":" << L_tmp_port << "]"); + if (getaddrinfo(L_tmp, + L_tmp_port, + &L_hints, + &addr) != 0) { + GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]"); + } else { + GEN_DEBUG(1, "add dst to m_addrs_dst"); + P_addr->m_addrs_dst.push_back(addr); + } + L_ptr = L_ptr + 5; + } else { + break; + } + } } } else { + GEN_DEBUG(1, "C_TransIP::m_active: false"); L_buf = P_buf ; L_ptr = strstr(L_buf, "standby="); if (L_ptr != NULL) { @@ -804,6 +879,7 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) { strcpy(P_addr->m_open, L_tmp_lag); } else { + GEN_DEBUG(1, "C_TransIP::without standby"); // if standby is not provided, default is dest L_buf = P_buf ; L_ptr = strstr(L_buf, "dest="); @@ -816,8 +892,41 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) { strlen(L_tmp)+1); strcpy(P_addr->m_open, L_tmp); } + L_ptr = L_buf; + while(1) { + L_ptr = strstr(L_ptr, "dest="); + if (L_ptr != NULL) { + struct addrinfo *addr; + struct addrinfo L_hints; + memset((char*)&L_hints, 0, sizeof(L_hints)); + L_hints.ai_flags = AI_PASSIVE; + L_hints.ai_family = PF_UNSPEC; + + sscanf(L_ptr + 5, "%[^;]*s", L_tmp); + + L_tmp_port[0] = '\0'; + char* delem = strstr(L_tmp, ":"); + if(delem != NULL) { + strncpy(L_tmp_port, delem + 1, 254); + (*delem) = '\0'; + } + + GEN_DEBUG(1, "dst b[" << L_tmp << ":" << L_tmp_port<< "]"); + if (getaddrinfo(L_tmp, + L_tmp_port, + &L_hints, + &addr) != 0) { + GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]"); + } else { + GEN_DEBUG(1, "add dst to m_addrs_dst"); + P_addr->m_addrs_dst.push_back(addr); + } + L_ptr = L_ptr + 5; + } else { + break; + } + } } - } } } diff --git a/seagull/trunk/src/library-trans-ip/S_IpAddr.hpp b/seagull/trunk/src/library-trans-ip/S_IpAddr.hpp index f66c6a3..ebfa409 100644 --- a/seagull/trunk/src/library-trans-ip/S_IpAddr.hpp +++ b/seagull/trunk/src/library-trans-ip/S_IpAddr.hpp @@ -22,6 +22,7 @@ #include "socket_t.hpp" #include "list_t.hpp" +#include "vector_t.hpp" #include "map_t.hpp" @@ -47,7 +48,8 @@ typedef struct _struct_ip_addr { long m_port_src ; char *m_ip_src ; T_SockAddrStorage m_addr_src ; - + vector_tm_addrs_src; + vector_tm_addrs_dst; } T_IpAddr, *T_pIpAddr ; void clear_IpAddr(T_pIpAddr P_IpAddr) ;