Skip to content

Commit 832ae69

Browse files
Support SCTP multihoming for client and server side
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"
1 parent 50ffc61 commit 832ae69

4 files changed

Lines changed: 222 additions & 42 deletions

File tree

seagull/trunk/src/library-trans-extsctp/C_SocketSCTP.cpp

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "C_Socket.hpp"
2424
#include "C_SocketSCTP.hpp"
2525

26+
#include <sys/socket.h>
27+
#include <netinet/in.h>
28+
#include <arpa/inet.h>
29+
2630

2731
#define MSGFLAG 0
2832
#define MAX_OUTGOING 128
@@ -100,7 +104,6 @@ void C_SocketSCTPListen::set_properties() {
100104
SOCKET_ERROR(1, "Unable to set SCTP_EVENTS option");
101105
}
102106

103-
// SCTP END
104107

105108
}
106109
// size of recv buf
@@ -182,10 +185,26 @@ int C_SocketSCTPListen::_open (size_t P_buffer_size,
182185
// set_properties() ;
183186

184187
/* bind the socket to the newly formed address */
185-
L_rc = bind(m_socket_id,
186-
(sockaddr *)(void *)&(m_source_addr_info->m_addr),
187-
SOCKADDR_IN_SIZE(&(m_source_addr_info->m_addr)));
188-
/* check there was no error */
188+
189+
struct sockaddr_storage *bind_addr = NULL;
190+
unsigned int cc = 0;
191+
SOCKET_DEBUG(0, "bind1 start");
192+
unsigned int bind_addr_count = m_source_addr_info->m_addrs_src.size();
193+
for (unsigned int i = 0; i < bind_addr_count; i++) {
194+
sockaddr_in *so = (sockaddr_in *)(m_source_addr_info->m_addrs_src[i]->ai_addr);
195+
size_t addrlen = m_source_addr_info->m_addrs_src[i]->ai_addrlen;
196+
SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr)
197+
<< ":" << ntohs(so->sin_port));
198+
bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen);
199+
memcpy((char*)bind_addr + cc, so, addrlen);
200+
cc += addrlen;
201+
}
202+
203+
SOCKET_DEBUG(0, "binding stop");
204+
L_rc = sctp_bindx(m_socket_id,
205+
(struct sockaddr*)bind_addr,
206+
bind_addr_count, SCTP_BINDX_ADD_ADDR);
207+
/* check there was no error */
189208
if (L_rc) {
190209
SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
191210
} else {
@@ -809,9 +828,22 @@ int C_SocketSCTPServer::_open_udp (size_t P_buffer_size,
809828
m_buffer_size = P_buffer_size ;
810829

811830
/* bind the socket to the newly formed address */
812-
L_rc = bind(m_socket_id,
813-
(sockaddr *)(void *)&(m_source_udp_addr_info->m_addr),
814-
SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr)));
831+
struct sockaddr_storage *bind_addr = NULL;
832+
unsigned int cc = 0;
833+
unsigned int bind_addr_count = m_source_udp_addr_info->m_addrs_src.size();
834+
for (unsigned int i = 0; i < bind_addr_count; i++) {
835+
sockaddr_in *so = (sockaddr_in *)(m_source_udp_addr_info->m_addrs_src[i]->ai_addr);
836+
size_t addrlen = m_source_udp_addr_info->m_addrs_src[i]->ai_addrlen;
837+
SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr)
838+
<< ":" << ntohs(so->sin_port));
839+
bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen);
840+
memcpy((char*)bind_addr + cc, so, addrlen);
841+
cc += addrlen;
842+
}
843+
844+
L_rc = sctp_bindx(m_socket_id,
845+
(struct sockaddr*)bind_addr,
846+
bind_addr_count, SCTP_BINDX_ADD_ADDR);
815847
/* check there was no error */
816848
if (L_rc) {
817849
SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
@@ -894,31 +926,45 @@ int C_SocketSCTPClient::_open(T_pOpenStatus P_status,
894926
if (L_rc == 0) {
895927

896928
if (m_type == E_SOCKET_TCP_MODE) {
929+
// SCTP MULTIHOMING CLIENT BINDING
930+
struct sockaddr_storage *bind_addr = NULL;
931+
unsigned int cc = 0;
932+
unsigned int bind_addr_count = m_remote_addr_info->m_addrs_src.size();
933+
for (unsigned int i = 0; i < bind_addr_count; i++) {
934+
sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_src[i]->ai_addr);
935+
size_t addrlen = m_remote_addr_info->m_addrs_src[i]->ai_addrlen;
936+
SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr)
937+
<< ":" << ntohs(so->sin_port));
938+
bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen);
939+
memcpy((char*)bind_addr + cc, so, addrlen);
940+
cc += addrlen;
941+
}
897942

898-
899-
/* struct sockaddr_storage *connect = NULL; */
900-
/* unsigned int cc = 0, count = 0; */
901-
/* if(m_remote_addr_info->m_addrs_dst > 0) { */
902-
/* // SCTP MULTIHOMING CONNECT */
903-
/* for (unsigned int i = 0; i < m_remote_addr_info->m_addrs_dst.size(); i++) { */
904-
/* sockaddr_in addr = m_remote_addr_info->m_addrs_dst[i]; */
905-
/* SOCKET_DEBUG(1, "multihoming client dst " << inet_ntoa(addr->sin_addr)); */
906-
/* } */
907-
/* } */
908-
/* connect = reallock */
909-
if(m_remote_addr_info->m_value != NULL) {
910-
L_rc = bind(m_socket_id,
911-
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
912-
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
913-
if (L_rc) {
914-
SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
943+
if(bind_addr_count > 0) {
944+
if(sctp_bindx(m_socket_id,
945+
(struct sockaddr*)bind_addr,
946+
bind_addr_count, SCTP_BINDX_ADD_ADDR)) {
947+
SOCKET_ERROR(1, "error bind client [" << strerror(errno) << "]");
915948
}
916949
}
917950

918-
L_rc = connect (m_socket_id,
919-
(struct sockaddr*)(void*)&(m_remote_addr_info->m_addr),
920-
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ;
921-
951+
952+
struct sockaddr_storage *connect_addr = NULL;
953+
cc = 0;
954+
unsigned int connect_addr_count = m_remote_addr_info->m_addrs_dst.size();
955+
for (unsigned int i = 0; i < connect_addr_count; i++) {
956+
sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_dst[i]->ai_addr);
957+
size_t addrlen = m_remote_addr_info->m_addrs_dst[i]->ai_addrlen;
958+
SOCKET_DEBUG(0, "connect to " << inet_ntoa(so->sin_addr)
959+
<< ":" << ntohs(so->sin_port));
960+
connect_addr = (sockaddr_storage*)realloc(connect_addr, cc + addrlen);
961+
memcpy((char*)connect_addr + cc, so, addrlen);
962+
cc += addrlen;
963+
}
964+
965+
L_rc = sctp_connectx(m_socket_id,
966+
(struct sockaddr*)connect_addr,
967+
connect_addr_count, 0);
922968
if (L_rc) {
923969
if (errno != EINPROGRESS) {
924970
SOCKET_ERROR(1, "connect failed ["
@@ -937,9 +983,23 @@ int C_SocketSCTPClient::_open(T_pOpenStatus P_status,
937983
*P_status = E_OPEN_OK ;
938984
}
939985
} else {
940-
L_rc = bind(m_socket_id,
941-
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
942-
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
986+
struct sockaddr_storage *bind_addr = NULL;
987+
unsigned int cc = 0;
988+
SOCKET_DEBUG(0, "bind start");
989+
unsigned int bind_addr_count = m_remote_addr_info->m_addrs_src.size();
990+
for (unsigned int i = 0; i < bind_addr_count; i++) {
991+
sockaddr_in *so = (sockaddr_in *)(m_remote_addr_info->m_addrs_src[i]->ai_addr);
992+
size_t addrlen = m_remote_addr_info->m_addrs_src[i]->ai_addrlen;
993+
SOCKET_DEBUG(0, "bind to " << inet_ntoa(so->sin_addr)
994+
<< ":" << ntohs(so->sin_port));
995+
bind_addr = (sockaddr_storage*)realloc(bind_addr, cc + addrlen);
996+
memcpy((char*)bind_addr + cc, so, addrlen);
997+
cc += addrlen;
998+
}
999+
1000+
L_rc = sctp_bindx(m_socket_id,
1001+
(struct sockaddr*)bind_addr,
1002+
bind_addr_count, SCTP_BINDX_ADD_ADDR);
9431003

9441004
if (L_rc) {
9451005
SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");

seagull/trunk/src/library-trans-extsctp/C_TransSCTP.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,31 @@
3030
#include "integer_t.hpp"
3131

3232
#define GEN_ERROR(l,a) iostream_error << a << iostream_endl << iostream_flush ;
33-
#ifdef DEBUG_MODE
33+
/* #ifdef DEBUG_MODE */
3434
#define GEN_DEBUG(l,a) iostream_error << a << iostream_endl << iostream_flush ;
35-
#else
36-
#define GEN_DEBUG(l,a)
37-
#endif
35+
/* #else */
36+
/* #define GEN_DEBUG(l,a) */
37+
/* #endif */
3838

3939

4040
int C_TransSCTP::config (T_pConfigValueList P_config_param_list) {
41-
GEN_DEBUG(1, "C_TransIP::config ()");
41+
GEN_DEBUG(1, "C_TransSCTP::config ()");
4242
m_logInfo = NULL ;
4343
m_logError = NULL ;
4444

4545
int L_ret = 0 ;
4646
T_ConfigValueList::iterator L_config_it ;
4747

48+
GEN_DEBUG(0, "111");
49+
4850
if (!P_config_param_list->empty()) {
51+
GEN_DEBUG(0, "112");
4952
for (L_config_it = P_config_param_list->begin() ;
5053
L_config_it != P_config_param_list->end();
5154
L_config_it++) {
55+
GEN_DEBUG(0, "113");
5256
L_ret = analyze_config(*L_config_it) ;
57+
GEN_DEBUG(0, "114");
5358
if (L_ret != 0) break ;
5459
}
5560
}
@@ -59,6 +64,10 @@ int C_TransSCTP::config (T_pConfigValueList P_config_param_list) {
5964

6065
int C_TransSCTP::analyze_config(T_ConfigValue& P_config) {
6166
int L_ret = 0 ;
67+
GEN_DEBUG(0, "name->value");
68+
GEN_DEBUG(0, P_config.m_name);
69+
GEN_DEBUG(0, P_config.m_value);
70+
GEN_DEBUG(0, "-----------");
6271
return (L_ret);
6372
}
6473

@@ -85,7 +94,7 @@ C_Socket* C_TransSCTP::open (int P_channel_id,
8594

8695

8796

88-
GEN_DEBUG(1, "C_TransIPTLS::open ()");
97+
GEN_DEBUG(1, "C_TransSCTP::open ()");
8998

9099
switch (P_Addr->m_umode) {
91100
case E_IP_USAGE_MODE_SERVER: {

seagull/trunk/src/library-trans-ip/C_TransIP.cpp

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
#include "Utils.hpp"
2222

2323
#include <cerrno>
24+
#include <string>
2425
#include <unistd.h>
26+
#include <sys/socket.h>
27+
#include <netinet/in.h>
28+
#include <arpa/inet.h>
2529

2630
#include <regex.h>
2731

@@ -743,7 +747,7 @@ bool C_TransIP::analyze_init_string(char *P_buf) {
743747

744748
bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
745749

746-
char L_tmp [255] ;
750+
char L_tmp [255], L_tmp_port[255];
747751
char L_tmp_lag [255] ;
748752
char *L_buf, *L_ptr ;
749753

@@ -775,10 +779,46 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
775779
char*,sizeof(char),
776780
strlen(L_tmp)+1);
777781
strcpy(P_addr->m_open_src, L_tmp);
778-
}
782+
783+
L_ptr = L_buf;
784+
while(1) {
785+
L_ptr = strstr(L_ptr, "source=");
786+
if (L_ptr != NULL) {
787+
struct addrinfo *addr;
788+
struct addrinfo L_hints;
789+
memset((char*)&L_hints, 0, sizeof(L_hints));
790+
L_hints.ai_flags = AI_PASSIVE;
791+
L_hints.ai_family = PF_UNSPEC;
792+
793+
sscanf(L_ptr+7, "%[^;]*s", L_tmp);
794+
795+
L_tmp_port[0] = '\0';
796+
char* delem = strstr(L_tmp, ":");
797+
if(delem != NULL) {
798+
strncpy(L_tmp_port, delem + 1, 254);
799+
(*delem) = '\0';
800+
}
801+
802+
GEN_DEBUG(1, "source [" << L_tmp << ":" << L_tmp_port << "]");
803+
if (getaddrinfo(L_tmp,
804+
L_tmp_port,
805+
&L_hints,
806+
&addr) != 0) {
807+
GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]");
808+
} else {
809+
GEN_DEBUG(1, "add src to m_addrs_dst");
810+
P_addr->m_addrs_src.push_back(addr);
811+
}
812+
L_ptr = L_ptr + 7;
813+
} else {
814+
break;
815+
}
816+
}
817+
}
779818
}
780819

781820
if (m_active) {
821+
GEN_DEBUG(1, "C_TransIP::m_active: true");
782822
L_buf = P_buf ;
783823
L_ptr = strstr(L_buf, "dest=");
784824
if (L_ptr != NULL) {
@@ -790,8 +830,43 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
790830
strlen(L_tmp)+1);
791831
strcpy(P_addr->m_open, L_tmp);
792832
}
833+
834+
L_ptr = L_buf;
835+
while(1) {
836+
L_ptr = strstr(L_ptr, "dest=");
837+
if (L_ptr != NULL) {
838+
struct addrinfo *addr;
839+
struct addrinfo L_hints;
840+
memset((char*)&L_hints, 0, sizeof(L_hints));
841+
L_hints.ai_flags = AI_PASSIVE;
842+
L_hints.ai_family = PF_UNSPEC;
843+
844+
sscanf(L_ptr + 5, "%[^;]*s", L_tmp);
845+
846+
L_tmp_port[0] = '\0';
847+
char* delem = strstr(L_tmp, ":");
848+
if(delem != NULL) {
849+
strncpy(L_tmp_port, delem + 1, 254);
850+
(*delem) = '\0';
851+
}
852+
GEN_DEBUG(1, "dst a[" << L_tmp << ":" << L_tmp_port << "]");
853+
if (getaddrinfo(L_tmp,
854+
L_tmp_port,
855+
&L_hints,
856+
&addr) != 0) {
857+
GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]");
858+
} else {
859+
GEN_DEBUG(1, "add dst to m_addrs_dst");
860+
P_addr->m_addrs_dst.push_back(addr);
861+
}
862+
L_ptr = L_ptr + 5;
863+
} else {
864+
break;
865+
}
866+
}
793867
}
794868
} else {
869+
GEN_DEBUG(1, "C_TransIP::m_active: false");
795870
L_buf = P_buf ;
796871
L_ptr = strstr(L_buf, "standby=");
797872
if (L_ptr != NULL) {
@@ -804,6 +879,7 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
804879
strcpy(P_addr->m_open, L_tmp_lag);
805880

806881
} else {
882+
GEN_DEBUG(1, "C_TransIP::without standby");
807883
// if standby is not provided, default is dest
808884
L_buf = P_buf ;
809885
L_ptr = strstr(L_buf, "dest=");
@@ -816,8 +892,41 @@ bool C_TransIP::analyze_open_string (char *P_buf, T_pIpAddr P_addr) {
816892
strlen(L_tmp)+1);
817893
strcpy(P_addr->m_open, L_tmp);
818894
}
895+
L_ptr = L_buf;
896+
while(1) {
897+
L_ptr = strstr(L_ptr, "dest=");
898+
if (L_ptr != NULL) {
899+
struct addrinfo *addr;
900+
struct addrinfo L_hints;
901+
memset((char*)&L_hints, 0, sizeof(L_hints));
902+
L_hints.ai_flags = AI_PASSIVE;
903+
L_hints.ai_family = PF_UNSPEC;
904+
905+
sscanf(L_ptr + 5, "%[^;]*s", L_tmp);
906+
907+
L_tmp_port[0] = '\0';
908+
char* delem = strstr(L_tmp, ":");
909+
if(delem != NULL) {
910+
strncpy(L_tmp_port, delem + 1, 254);
911+
(*delem) = '\0';
912+
}
913+
914+
GEN_DEBUG(1, "dst b[" << L_tmp << ":" << L_tmp_port<< "]");
915+
if (getaddrinfo(L_tmp,
916+
L_tmp_port,
917+
&L_hints,
918+
&addr) != 0) {
919+
GEN_DEBUG(1, "Unknown host: [" << L_tmp << "]");
920+
} else {
921+
GEN_DEBUG(1, "add dst to m_addrs_dst");
922+
P_addr->m_addrs_dst.push_back(addr);
923+
}
924+
L_ptr = L_ptr + 5;
925+
} else {
926+
break;
927+
}
928+
}
819929
}
820-
821930
}
822931
}
823932
}

0 commit comments

Comments
 (0)