Commit dfa01216 authored by Robert Schmidt's avatar Robert Schmidt

Rewrite sctp_create_new_listener() to handle DNS, IPv6

Rewrite sctp_create_new_listener() to use getaddrinfo() to look up
IPv4/IPv6 addresses via a common interface. This allows to use e.g. DNS,
and enables the SCTP library to listen on IPv6 ports.

To support the above, the corresponding message is changed to not take
an IPv4 address on 4 bytes (and separate IPv6), but a single name that
will be resolved via getaddrinfo()

The previous init message used to allow multiple IPv4/IPv6 addresses;
since this is not used anywhere, remove the corresponding functionality.

Modify all uses of this ITTI message to copy te SCTP init bind addr into
ITTI message.
parent 0d128f9c
......@@ -128,14 +128,7 @@ typedef struct sctp_data_ind_s {
} sctp_data_ind_t;
typedef struct sctp_init_s {
/* Request usage of ipv4 */
unsigned ipv4:1;
/* Request usage of ipv6 */
unsigned ipv6:1;
uint8_t nb_ipv4_addr;
uint32_t ipv4_address[10];
uint8_t nb_ipv6_addr;
char *ipv6_address[10];
char *bind_address;
uint16_t port;
uint32_t ppid;
} sctp_init_t;
......
......@@ -1873,21 +1873,15 @@ void cuup_init_n3(instance_t instance)
void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr)
{
LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n");
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG);
message_p->ittiMsg.sctp_init.port = E1AP_PORT_NUMBER;
message_p->ittiMsg.sctp_init.ppid = E1AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
size_t addr_len = strlen(my_addr) + 1;
LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket) for %s len %ld\n", my_addr, addr_len);
MessageDef *message_p = itti_alloc_new_message_sized(TASK_CUCP_E1, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len);
sctp_init_t *init = &SCTP_INIT_MSG(message_p);
init->port = E1AP_PORT_NUMBER;
init->ppid = E1AP_SCTP_PPID;
char *addr_buf = (char *) (init + 1); // address after sctp_init ITTI message end, allocated above
init->bind_address = addr_buf;
memcpy(addr_buf, my_addr, addr_len);
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
......
......@@ -96,25 +96,20 @@ static void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *s
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static void cu_task_send_sctp_init_req(instance_t instance, char *my_addr) {
static void cu_task_send_sctp_init_req(instance_t instance, char *my_addr)
{
// 1. get the itti msg, and retrive the nb_id from the message
// 2. use RC.rrc[nb_id] to fill the sctp_init_t with the ip, port
// 3. creat an itti message to init
LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n");
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_CU_F1, 0, SCTP_INIT_MSG);
message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER;
message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
size_t addr_len = strlen(my_addr) + 1;
LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket) for %s len %ld\n", my_addr, addr_len);
MessageDef *message_p = itti_alloc_new_message_sized(TASK_CU_F1, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len);
sctp_init_t *init = &SCTP_INIT_MSG(message_p);
init->port = F1AP_PORT_NUMBER;
init->ppid = F1AP_SCTP_PPID;
char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above
init->bind_address = addr_buf;
memcpy(addr_buf, my_addr, addr_len);
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
......
......@@ -227,29 +227,16 @@ int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1;
MessageDef *message = itti_alloc_new_message_sized(TASK_M2AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len);
sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mce_port_for_M2C;
sctp_init->ppid = M2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
char *addr_buf = (char *) (sctp_init + 1);
sctp_init->bind_address = addr_buf;
memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len);
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
......@@ -502,41 +489,16 @@ void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_m
// 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
// 3. creat an itti message to init
LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n");
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG);
// if( m2ap_mce_sctp_req == NULL ){
// message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER;
// message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
// message_p->ittiMsg.sctp_init.ipv4 = 1;
// message_p->ittiMsg.sctp_init.ipv6 = 0;
// message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
// //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
// message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7");
// /*
// * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
// * * * * Disable it for now.
// */
// message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
// message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
// }else{
message_p->ittiMsg.sctp_init.port = m2ap_mce_sctp_req->mce_port_for_M2C;
message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
// }
size_t addr_len = strlen(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address) + 1;
LOG_I(M2AP, "M2AP_SCTP_REQ(create socket) for %s len %ld\n", m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address, addr_len);
MessageDef *message_p = itti_alloc_new_message_sized (TASK_M2AP_MCE, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len);
sctp_init_t *init = &SCTP_INIT_MSG(message_p);
init->port = m2ap_mce_sctp_req->mce_port_for_M2C;
init->ppid = M2AP_SCTP_PPID;
char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above
init->bind_address = addr_buf;
memcpy(addr_buf, m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address, addr_len);
itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
}
......
......@@ -229,29 +229,16 @@ int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M2AP_ENB, 0, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1;
MessageDef *message = itti_alloc_new_message_sized(TASK_M2AP_ENB, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len);
sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = enb_port_for_M2C;
sctp_init->ppid = M2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
char *addr_buf = (char *) (sctp_init + 1);
sctp_init->bind_address = addr_buf;
memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len);
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
......
......@@ -217,29 +217,16 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_X2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_X2AP, 0, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1;
MessageDef *message = itti_alloc_new_message_sized(TASK_X2AP, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len);
sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = enb_port_for_X2C;
sctp_init->ppid = X2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
char *addr_buf = (char *) (sctp_init + 1);
sctp_init->bind_address = addr_buf;
memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len);
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
......
......@@ -225,29 +225,16 @@ int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M3C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1;
MessageDef *message = itti_alloc_new_message_sized(TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len);
sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mce_port_for_M3C;
sctp_init->ppid = M3AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
char *addr_buf = (char *) (sctp_init + 1);
sctp_init->bind_address = addr_buf;
memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len);
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
......
......@@ -227,29 +227,16 @@ int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mme_port_for_M3C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
size_t addr_len = strlen(local_ip_addr->ipv4_address) + 1;
MessageDef *message = itti_alloc_new_message_sized(TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ, sizeof(sctp_init_t) + addr_len);
sctp_init_t *sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mme_port_for_M3C;
sctp_init->ppid = M3AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
char *addr_buf = (char *) (sctp_init + 1);
sctp_init->bind_address = addr_buf;
memcpy(addr_buf, local_ip_addr->ipv4_address, addr_len);
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
......@@ -502,37 +489,22 @@ void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_m
// 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
// 3. creat an itti message to init
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG);
if(m3ap_mme_sctp_req==NULL) {
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n");
message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER;
message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.8");
}else{
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) %s\n",m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address);
message_p->ittiMsg.sctp_init.port = m3ap_mme_sctp_req->mme_port_for_M3C;
message_p->ittiMsg.sctp_init.ppid = M3AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address);
}
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
size_t addr_len = m3ap_mme_sctp_req != NULL ? strlen(m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address) + 1 : strlen("127.0.0.8") + 1; // the previous code might hardcode, support this
MessageDef *message_p = itti_alloc_new_message_sized(TASK_M3AP_MME, 0, SCTP_INIT_MSG, sizeof(sctp_init_t) + addr_len);
sctp_init_t *init = &SCTP_INIT_MSG(message_p);
char *addr_buf = (char *) (init + 1); // address after ITTI message end, allocated above
init->bind_address = addr_buf;
if (m3ap_mme_sctp_req == NULL) {
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n");
init->port = M3AP_PORT_NUMBER;
init->ppid = M3AP_SCTP_PPID;
memcpy(addr_buf, "127.0.0.8", addr_len);
} else {
LOG_I(M3AP, "M3AP_SCTP_REQ(create socket) for %s %ld\n", m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address, addr_len);
init->port = m3ap_mme_sctp_req->mme_port_for_M3C;
init->ppid = M3AP_SCTP_PPID;
memcpy(addr_buf, m3ap_mme_sctp_req->mme_m3_ip_address.ipv4_address, addr_len);
}
itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
}
......
......@@ -598,85 +598,44 @@ static int sctp_close_association(sctp_close_association_t *close_association_p)
return 0;
}
//------------------------------------------------------------------------------
static int sctp_create_new_listener(
const instance_t instance,
const task_id_t requestor,
sctp_init_t *init_p,
int server_type)
static int sctp_create_new_listener(const instance_t instance, const task_id_t requestor, sctp_init_t *init_p, int server_type)
{
struct sctp_event_subscribe event={0};
struct sockaddr *addr = NULL;
struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
uint16_t i = 0, j = 0;
int sd = 0;
int used_addresses = 0;
DevAssert(init_p != NULL);
if (init_p->ipv4 == 0 && init_p->ipv6 == 0) {
SCTP_ERROR("Illegal IP configuration upper layer should request at"
"least ipv4 and/or ipv6 config\n");
return -1;
}
if ((used_addresses = init_p->nb_ipv4_addr + init_p->nb_ipv6_addr) == 0) {
SCTP_WARN("No address provided...\n");
return -1;
}
addr = calloc(used_addresses, sizeof(struct sockaddr));
SCTP_DEBUG("Creating new listen socket on port %u with\n", init_p->port);
if (init_p->ipv4 == 1) {
struct sockaddr_in *ip4_addr;
DevAssert(init_p != NULL);
DevAssert(init_p->bind_address != NULL);
int in_streams = 1;
int out_streams = 1;
SCTP_DEBUG("ipv4 addresses:\n");
for (i = 0; i < init_p->nb_ipv4_addr; i++) {
SCTP_DEBUG("\t- "IPV4_ADDR"\n", IPV4_ADDR_FORMAT(init_p->ipv4_address[i]));
ip4_addr = (struct sockaddr_in *)&addr[i];
ip4_addr->sin_family = AF_INET;
ip4_addr->sin_port = htons(init_p->port);
ip4_addr->sin_addr.s_addr = init_p->ipv4_address[i];
}
}
/* local address: IPv4 has priority, but can also handle IPv6 */
const char *local = init_p->bind_address;
if (init_p->ipv6 == 1) {
struct sockaddr_in6 *ip6_addr;
struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_SCTP};
struct addrinfo *serv;
SCTP_DEBUG("ipv6 addresses:\n");
char port[12];
snprintf(port, sizeof(port), "%d", init_p->port);
int status = getaddrinfo(local, port, &hints, &serv);
AssertFatal(status == 0, "getaddrinfo() failed: %s\n", gai_strerror(status));
for (j = 0; j < init_p->nb_ipv6_addr; j++) {
SCTP_DEBUG("\t- %s\n", init_p->ipv6_address[j]);
ip6_addr = (struct sockaddr_in6 *)&addr[i + j];
ip6_addr->sin6_family = AF_INET6;
ip6_addr->sin6_port = htons(init_p->port);
int sd;
struct addrinfo *p = NULL;
for (p = serv; p != NULL; p = p->ai_next) {
char buf[512];
const char *ip = print_ip(p, buf, sizeof(buf));
SCTP_DEBUG("Trying %s for server socket creation\n", ip);
if (inet_pton(AF_INET6, init_p->ipv6_address[j],
ip6_addr->sin6_addr.s6_addr) <= 0) {
SCTP_WARN("Provided ipv6 address %s is not valid\n",
init_p->ipv6_address[j]);
}
}
/* SOCK_SEQPACKET to be able to reuse(?) socket through SCTP_INIT_MSG_MULTI_REQ */
int socktype = server_type ? SOCK_SEQPACKET : SOCK_STREAM;
if ((sd = socket(serv->ai_family, socktype, serv->ai_protocol)) == -1) {
SCTP_WARN("Socket creation failed: %s\n", strerror(errno));
continue;
}
if (server_type) {
if ((sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) {
SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno);
free(addr);
return -1;
}
}
else {
if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) {
SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno);
free(addr);
return -1;
}
}
/* we assume we can set options, or something is likely broken; the
* connection won't operate properly */
int ret = sctp_set_init_opt(sd, in_streams, out_streams, 0, 0);
AssertFatal(ret == 0, "sctp_set_init_opt() failed\n");
struct sctp_event_subscribe event = {0};
event.sctp_data_io_event = 1;
event.sctp_association_event = 1;
event.sctp_address_event = 1;
......@@ -685,83 +644,55 @@ static int sctp_create_new_listener(
event.sctp_shutdown_event = 1;
event.sctp_partial_delivery_event = 1;
if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event,
8) < 0) {
SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno);
if (sd != -1) {
close(sd);
sd = -1;
}
free(addr);
return -1;
}
sctp_cnx = calloc(1, sizeof(*sctp_cnx));
/* as above */
ret = setsockopt(sd, serv->ai_protocol, SCTP_EVENTS, &event, 8);
AssertFatal(ret == 0, "setsockopt() IPPROTO_SCTP_EVENTS failed: %s\n", strerror(errno));
if (server_type) {
sctp_cnx->connection_type = SCTP_TYPE_MULTI_SERVER;
}
else {
sctp_cnx->connection_type = SCTP_TYPE_SERVER;
/* if that fails, we will try the next address */
ret = sctp_bindx(sd, p->ai_addr, 1, SCTP_BINDX_ADD_ADDR);
if (ret != 0) {
SCTP_WARN("sctp_bindx() SCTP_BINDX_ADD_ADDR failed: errno %d %s\n", errno, strerror(errno));
close(sd);
continue;
}
sctp_cnx->sd = sd;
sctp_cnx->local_port = init_p->port;
sctp_cnx->in_streams = 32;
sctp_cnx->out_streams = 32;
sctp_cnx->ppid = init_p->ppid;
sctp_cnx->task_id = requestor;
sctp_cnx->instance = instance;
/* Some pre-bind socket configuration */
if (sctp_set_init_opt(sd,
sctp_cnx->in_streams,
sctp_cnx->out_streams,
0,
0) < 0) {
goto err;
if (listen(sd, 5) < 0) {
SCTP_WARN("listen() failed: %s:%d\n", strerror(errno), errno);
close(sd);
return -1;
}
if (sctp_bindx(sd, addr, used_addresses, SCTP_BINDX_ADD_ADDR) != 0) {
SCTP_ERROR("sctp_bindx: %s:%d\n", strerror(errno), errno);
free(sctp_cnx);
sctp_cnx = NULL;
return -1;
}
SCTP_DEBUG("Created listen socket %d on %s:%s local %s\n", sd, ip, port, local);
if (listen(sd, 5) < 0) {
SCTP_ERROR("listen: %s:%d\n", strerror(errno), errno);
free(sctp_cnx);
sctp_cnx = NULL;
return -1;
}
SCTP_DEBUG("Created listen socket: %d\n", sd);
/* Insert new element at end of list */
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
sctp_nb_cnx++;
break;
}
/* Add the socket to list of fd monitored by ITTI */
itti_subscribe_event_fd(TASK_SCTP, sd);
freeaddrinfo(serv);
return sd;
err:
if (p == NULL) {
SCTP_ERROR("could not open server socket, no SCTP listener active\n");
return -1;
}
if (sd != -1) {
close(sd);
sd = -1;
}
struct sctp_cnx_list_elm_s *sctp_cnx = calloc(1, sizeof(*sctp_cnx));
AssertFatal(sctp_cnx != NULL, "out of memory\n");
if (sctp_cnx != NULL) {
free(sctp_cnx);
sctp_cnx = NULL;
}
sctp_cnx->connection_type = server_type ? SCTP_TYPE_MULTI_SERVER : SCTP_TYPE_SERVER;
sctp_cnx->sd = sd;
sctp_cnx->local_port = init_p->port;
sctp_cnx->in_streams = in_streams;
sctp_cnx->out_streams = out_streams;
sctp_cnx->ppid = init_p->ppid;
sctp_cnx->task_id = requestor;
sctp_cnx->instance = instance;
/* Insert new element at end of list */
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
sctp_nb_cnx++;
if (addr != NULL) {
free(addr);
addr = NULL;
}
/* Add the socket to list of fd monitored by ITTI */
itti_subscribe_event_fd(TASK_SCTP, sd);
return -1;
return sd;
}
//------------------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment