Skip to content

Commit

Permalink
Support SCTP multihoming for client and server side
Browse files Browse the repository at this point in the history
Parse multiple IPs from channels args like this:
  open-args="mode=client;dest=172.17.0.1:3868;dest=172.17.0.2:3868"
Support server and client binding to multiple source ip like this:
  open-args="mode=server;source=172.17.1.1:3868;source=172.17.1.2"
  • Loading branch information
platinumthinker committed Dec 15, 2018
1 parent 81db791 commit a62d4ce
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 25 deletions.
4 changes: 2 additions & 2 deletions docker/ubuntu-16.04/Dockerfile
Original file line number Diff line number Diff line change
@@ -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 \
Expand All @@ -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 \
Expand Down
2 changes: 1 addition & 1 deletion docker/ubuntu-18.04/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
110 changes: 94 additions & 16 deletions seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include "C_Socket.hpp"
#include "C_SocketSCTP.hpp"

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define MSGFLAG 0
#define MAX_OUTGOING 128
Expand Down Expand Up @@ -100,7 +104,6 @@ void C_SocketSCTPListen::set_properties() {
SOCKET_ERROR(1, "Unable to set SCTP_EVENTS option");
}

// SCTP END

}
// size of recv buf
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) << "]");
Expand Down Expand Up @@ -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 ["
Expand All @@ -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) << "]");
Expand Down
4 changes: 2 additions & 2 deletions seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;

Expand Down Expand Up @@ -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: {
Expand Down
115 changes: 112 additions & 3 deletions seagull/trunk/src/library-trans-ip/C_TransIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
#include "Utils.hpp"

#include <cerrno>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <regex.h>

Expand Down Expand Up @@ -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 ;

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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=");
Expand All @@ -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;
}
}
}

}
}
}
Expand Down
4 changes: 3 additions & 1 deletion seagull/trunk/src/library-trans-ip/S_IpAddr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "socket_t.hpp"
#include "list_t.hpp"
#include "vector_t.hpp"

#include "map_t.hpp"

Expand All @@ -47,7 +48,8 @@ typedef struct _struct_ip_addr {
long m_port_src ;
char *m_ip_src ;
T_SockAddrStorage m_addr_src ;

vector_t<struct addrinfo *>m_addrs_src;
vector_t<struct addrinfo *>m_addrs_dst;
} T_IpAddr, *T_pIpAddr ;

void clear_IpAddr(T_pIpAddr P_IpAddr) ;
Expand Down

0 comments on commit a62d4ce

Please sign in to comment.