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 50ffc61 commit 832ae69
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 42 deletions.
124 changes: 92 additions & 32 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,31 +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;
}


/* struct sockaddr_storage *connect = NULL; */
/* unsigned int cc = 0, count = 0; */
/* if(m_remote_addr_info->m_addrs_dst > 0) { */
/* // SCTP MULTIHOMING CONNECT */
/* for (unsigned int i = 0; i < m_remote_addr_info->m_addrs_dst.size(); i++) { */
/* sockaddr_in addr = m_remote_addr_info->m_addrs_dst[i]; */
/* SOCKET_DEBUG(1, "multihoming client dst " << inet_ntoa(addr->sin_addr)); */
/* } */
/* } */
/* connect = reallock */
if(m_remote_addr_info->m_value != NULL) {
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)));
if (L_rc) {
SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
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 @@ -937,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
21 changes: 15 additions & 6 deletions seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,31 @@
#include "integer_t.hpp"

#define GEN_ERROR(l,a) iostream_error << a << iostream_endl << iostream_flush ;
#ifdef DEBUG_MODE
/* #ifdef DEBUG_MODE */
#define GEN_DEBUG(l,a) iostream_error << a << iostream_endl << iostream_flush ;
#else
#define GEN_DEBUG(l,a)
#endif
/* #else */
/* #define GEN_DEBUG(l,a) */
/* #endif */


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 ;

int L_ret = 0 ;
T_ConfigValueList::iterator L_config_it ;

GEN_DEBUG(0, "111");

if (!P_config_param_list->empty()) {
GEN_DEBUG(0, "112");
for (L_config_it = P_config_param_list->begin() ;
L_config_it != P_config_param_list->end();
L_config_it++) {
GEN_DEBUG(0, "113");
L_ret = analyze_config(*L_config_it) ;
GEN_DEBUG(0, "114");
if (L_ret != 0) break ;
}
}
Expand All @@ -59,6 +64,10 @@ int C_TransSCTP::config (T_pConfigValueList P_config_param_list) {

int C_TransSCTP::analyze_config(T_ConfigValue& P_config) {
int L_ret = 0 ;
GEN_DEBUG(0, "name->value");
GEN_DEBUG(0, P_config.m_name);
GEN_DEBUG(0, P_config.m_value);
GEN_DEBUG(0, "-----------");
return (L_ret);
}

Expand All @@ -85,7 +94,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
Loading

0 comments on commit 832ae69

Please sign in to comment.